<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <updated></updated>
  <generator>https://yabu.me</generator>

  <title>Nostr notes by </title>
  <author>
    <name></name>
  </author>
  <link rel="self" type="application/atom+xml" href="https://yabu.me/npub1xucxy58x92hmu9l3l50wykjnnungupzdw5t8xnrw8zwxmee88tysqg43rm.rss" />
  <link href="https://yabu.me/npub1xucxy58x92hmu9l3l50wykjnnungupzdw5t8xnrw8zwxmee88tysqg43rm" />
  <id>https://yabu.me/npub1xucxy58x92hmu9l3l50wykjnnungupzdw5t8xnrw8zwxmee88tysqg43rm</id>
  <icon></icon>
  <logo></logo>




  <entry>
    <id>https://yabu.me/nevent1qqsztcrtvlyetk4y30uwcf3g79lkdjyzdnlt706846rfh7206x6604szyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj6gw9c9</id>
    
      <title type="html">Build manifest for get_file_hash v0.3.3</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsztcrtvlyetk4y30uwcf3g79lkdjyzdnlt706846rfh7206x6604szyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj6gw9c9" />
    <content type="html">
      In reply to &lt;a href=&#39;/nevent1qqsq8uyzf73yztqlyvklfe3fc4arddmlr9e5ymxhnqgnvk2y9a2lmfq9fp4gu&#39;&gt;nevent1q…p4gu&lt;/a&gt;&lt;br/&gt;_________________________&lt;br/&gt;&lt;br/&gt;Build manifest for get_file_hash v0.3.3
    </content>
    <updated>2026-04-04T01:48:52Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsq8uyzf73yztqlyvklfe3fc4arddmlr9e5ymxhnqgnvk2y9a2lmfqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj80vf59</id>
    
      <title type="html">&amp;lt;?xml version=&amp;#39;1.0&amp;#39; ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsq8uyzf73yztqlyvklfe3fc4arddmlr9e5ymxhnqgnvk2y9a2lmfqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj80vf59" />
    <content type="html">
      &amp;lt;?xml version=&amp;#39;1.0&amp;#39; encoding=&amp;#39;windows-1252&amp;#39;?&amp;gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  Copyright (C) 2017 Christopher R. Field.&lt;br/&gt;&lt;br/&gt;  Licensed under the Apache License, Version 2.0 (the &amp;#34;License&amp;#34;);&lt;br/&gt;  you may not use this file except in compliance with the License.&lt;br/&gt;  You may obtain a copy of the License at&lt;br/&gt;&lt;br/&gt;  &lt;a href=&#34;http://www.apache.org/licenses/LICENSE-2.0&#34;&gt;http://www.apache.org/licenses/LICENSE-2.0&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;  Unless required by applicable law or agreed to in writing, software&lt;br/&gt;  distributed under the License is distributed on an &amp;#34;AS IS&amp;#34; BASIS,&lt;br/&gt;  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;br/&gt;  See the License for the specific language governing permissions and&lt;br/&gt;  limitations under the License.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  The &amp;#34;cargo wix&amp;#34; subcommand provides a variety of predefined variables available&lt;br/&gt;  for customization of this template. The values for each variable are set at&lt;br/&gt;  installer creation time. The following variables are available:&lt;br/&gt;&lt;br/&gt;  TargetTriple      = The rustc target triple name.&lt;br/&gt;  TargetEnv         = The rustc target environment. This is typically either&lt;br/&gt;                      &amp;#34;msvc&amp;#34; or &amp;#34;gnu&amp;#34; depending on the toolchain downloaded and&lt;br/&gt;                      installed.&lt;br/&gt;  TargetVendor      = The rustc target vendor. This is typically &amp;#34;pc&amp;#34;, but Rust&lt;br/&gt;                      does support other vendors, like &amp;#34;uwp&amp;#34;.&lt;br/&gt;  CargoTargetBinDir = The complete path to the directory containing the&lt;br/&gt;                      binaries (exes) to include. The default would be&lt;br/&gt;                      &amp;#34;target\release\&amp;#34;. If an explicit rustc target triple is&lt;br/&gt;                      used, i.e. cross-compiling, then the default path would&lt;br/&gt;                      be &amp;#34;target\&amp;lt;CARGO_TARGET&amp;gt;\&amp;lt;CARGO_PROFILE&amp;gt;&amp;#34;,&lt;br/&gt;                      where &amp;#34;&amp;lt;CARGO_TARGET&amp;gt;&amp;#34; is replaced with the &amp;#34;CargoTarget&amp;#34;&lt;br/&gt;                      variable value and &amp;#34;&amp;lt;CARGO_PROFILE&amp;gt;&amp;#34; is replaced with the&lt;br/&gt;                      value from the &amp;#34;CargoProfile&amp;#34; variable. This can also&lt;br/&gt;                      be overridden manually with the &amp;#34;target-bin-dir&amp;#34; flag.&lt;br/&gt;  CargoTargetDir    = The path to the directory for the build artifacts, i.e.&lt;br/&gt;                      &amp;#34;target&amp;#34;.&lt;br/&gt;  CargoProfile      = The cargo profile used to build the binaries&lt;br/&gt;                      (usually &amp;#34;debug&amp;#34; or &amp;#34;release&amp;#34;).&lt;br/&gt;  Version           = The version for the installer. The default is the&lt;br/&gt;                      &amp;#34;Major.Minor.Fix&amp;#34; semantic versioning number of the Rust&lt;br/&gt;                      package.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  Please do not remove these pre-processor If-Else blocks. These are used with&lt;br/&gt;  the `cargo wix` subcommand to automatically determine the installation&lt;br/&gt;  destination for 32-bit versus 64-bit installers. Removal of these lines will&lt;br/&gt;  cause installation errors.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&amp;lt;?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64 ?&amp;gt;&lt;br/&gt;    &amp;lt;?define PlatformProgramFilesFolder = &amp;#34;ProgramFiles64Folder&amp;#34; ?&amp;gt;&lt;br/&gt;&amp;lt;?else ?&amp;gt;&lt;br/&gt;    &amp;lt;?define PlatformProgramFilesFolder = &amp;#34;ProgramFilesFolder&amp;#34; ?&amp;gt;&lt;br/&gt;&amp;lt;?endif ?&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;Wix xmlns=&amp;#39;&lt;a href=&#34;http://schemas.microsoft.com/wix/2006/wi&amp;#39;&amp;gt&#34;&gt;http://schemas.microsoft.com/wix/2006/wi&amp;#39;&amp;gt&lt;/a&gt;;&lt;br/&gt;&lt;br/&gt;    &amp;lt;Product&lt;br/&gt;        Id=&amp;#39;*&amp;#39;&lt;br/&gt;        Name=&amp;#39;get_file_hash&amp;#39;&lt;br/&gt;        UpgradeCode=&amp;#39;DED69220-26E3-4406-B564-7F2B58C56F57&amp;#39;&lt;br/&gt;        Manufacturer=&amp;#39;gnostr admin@gnostr.org&amp;#39;&lt;br/&gt;        Language=&amp;#39;1033&amp;#39;&lt;br/&gt;        Codepage=&amp;#39;1252&amp;#39;&lt;br/&gt;        Version=&amp;#39;$(var.Version)&amp;#39;&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Package Id=&amp;#39;*&amp;#39;&lt;br/&gt;            Keywords=&amp;#39;Installer&amp;#39;&lt;br/&gt;            Description=&amp;#39;A utility crate providing a procedural macro to compute and embed file hashes at compile time.&amp;#39;&lt;br/&gt;            Manufacturer=&amp;#39;gnostr admin@gnostr.org&amp;#39;&lt;br/&gt;            InstallerVersion=&amp;#39;450&amp;#39;&lt;br/&gt;            Languages=&amp;#39;1033&amp;#39;&lt;br/&gt;            Compressed=&amp;#39;yes&amp;#39;&lt;br/&gt;            InstallScope=&amp;#39;perMachine&amp;#39;&lt;br/&gt;            SummaryCodepage=&amp;#39;1252&amp;#39;&lt;br/&gt;            /&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;MajorUpgrade&lt;br/&gt;            Schedule=&amp;#39;afterInstallInitialize&amp;#39;&lt;br/&gt;            DowngradeErrorMessage=&amp;#39;A newer version of [ProductName] is already installed. Setup will now exit.&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Media Id=&amp;#39;1&amp;#39; Cabinet=&amp;#39;media1.cab&amp;#39; EmbedCab=&amp;#39;yes&amp;#39; DiskPrompt=&amp;#39;CD-ROM #1&amp;#39;/&amp;gt;&lt;br/&gt;        &amp;lt;Property Id=&amp;#39;DiskPrompt&amp;#39; Value=&amp;#39;get_file_hash Installation&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Directory Id=&amp;#39;TARGETDIR&amp;#39; Name=&amp;#39;SourceDir&amp;#39;&amp;gt;&lt;br/&gt;            &amp;lt;Directory Id=&amp;#39;$(var.PlatformProgramFilesFolder)&amp;#39; Name=&amp;#39;PFiles&amp;#39;&amp;gt;&lt;br/&gt;                &amp;lt;Directory Id=&amp;#39;APPLICATIONFOLDER&amp;#39; Name=&amp;#39;get_file_hash&amp;#39;&amp;gt;&lt;br/&gt;                    &lt;br/&gt;                    &amp;lt;!--&lt;br/&gt;                      Enabling the license sidecar file in the installer is a four step process:&lt;br/&gt;&lt;br/&gt;                      1. Uncomment the `Component` tag and its contents.&lt;br/&gt;                      2. Change the value for the `Source` attribute in the `File` tag to a path&lt;br/&gt;                         to the file that should be included as the license sidecar file. The path&lt;br/&gt;                         can, and probably should be, relative to this file.&lt;br/&gt;                      3. Change the value for the `Name` attribute in the `File` tag to the&lt;br/&gt;                         desired name for the file when it is installed alongside the `bin` folder&lt;br/&gt;                         in the installation directory. This can be omitted if the desired name is&lt;br/&gt;                         the same as the file name.&lt;br/&gt;                      4. Uncomment the `ComponentRef` tag with the Id attribute value of &amp;#34;License&amp;#34;&lt;br/&gt;                         further down in this file.&lt;br/&gt;                    --&amp;gt;&lt;br/&gt;                    &amp;lt;!--&lt;br/&gt;                    &amp;lt;Component Id=&amp;#39;License&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                        &amp;lt;File Id=&amp;#39;LicenseFile&amp;#39; Name=&amp;#39;ChangeMe&amp;#39; DiskId=&amp;#39;1&amp;#39; Source=&amp;#39;C:\Path\To\File&amp;#39; KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                    &amp;lt;/Component&amp;gt;&lt;br/&gt;                    --&amp;gt;&lt;br/&gt;&lt;br/&gt;                    &amp;lt;Directory Id=&amp;#39;Bin&amp;#39; Name=&amp;#39;bin&amp;#39;&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;Path&amp;#39; Guid=&amp;#39;8DB39A25-8B99-4C25-8CF5-4704353C7C6E&amp;#39; KeyPath=&amp;#39;yes&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;Environment&lt;br/&gt;                                Id=&amp;#39;PATH&amp;#39;&lt;br/&gt;                                Name=&amp;#39;PATH&amp;#39;&lt;br/&gt;                                Value=&amp;#39;[Bin]&amp;#39;&lt;br/&gt;                                Permanent=&amp;#39;no&amp;#39;&lt;br/&gt;                                Part=&amp;#39;last&amp;#39;&lt;br/&gt;                                Action=&amp;#39;set&amp;#39;&lt;br/&gt;                                System=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;binary0&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;File&lt;br/&gt;                                Id=&amp;#39;exe0&amp;#39;&lt;br/&gt;                                Name=&amp;#39;get_file_hash.exe&amp;#39;&lt;br/&gt;                                DiskId=&amp;#39;1&amp;#39;&lt;br/&gt;                                Source=&amp;#39;$(var.CargoTargetBinDir)\get_file_hash.exe&amp;#39;&lt;br/&gt;                                KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;binary1&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;File&lt;br/&gt;                                Id=&amp;#39;exe1&amp;#39;&lt;br/&gt;                                Name=&amp;#39;readme.exe&amp;#39;&lt;br/&gt;                                DiskId=&amp;#39;1&amp;#39;&lt;br/&gt;                                Source=&amp;#39;$(var.CargoTargetBinDir)\readme.exe&amp;#39;&lt;br/&gt;                                KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                    &amp;lt;/Directory&amp;gt;&lt;br/&gt;                &amp;lt;/Directory&amp;gt;&lt;br/&gt;            &amp;lt;/Directory&amp;gt;&lt;br/&gt;        &amp;lt;/Directory&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Feature&lt;br/&gt;            Id=&amp;#39;Binaries&amp;#39;&lt;br/&gt;            Title=&amp;#39;Application&amp;#39;&lt;br/&gt;            Description=&amp;#39;Installs all binaries and the license.&amp;#39;&lt;br/&gt;            Level=&amp;#39;1&amp;#39;&lt;br/&gt;            ConfigurableDirectory=&amp;#39;APPLICATIONFOLDER&amp;#39;&lt;br/&gt;            AllowAdvertise=&amp;#39;no&amp;#39;&lt;br/&gt;            Display=&amp;#39;expand&amp;#39;&lt;br/&gt;            Absent=&amp;#39;disallow&amp;#39;&amp;gt;&lt;br/&gt;            &lt;br/&gt;            &amp;lt;!--&lt;br/&gt;              Uncomment the following `ComponentRef` tag to add the license&lt;br/&gt;              sidecar file to the installer.&lt;br/&gt;            --&amp;gt;&lt;br/&gt;            &amp;lt;!--&amp;lt;ComponentRef Id=&amp;#39;License&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;            &amp;lt;ComponentRef Id=&amp;#39;binary0&amp;#39;/&amp;gt;&lt;br/&gt;            &amp;lt;ComponentRef Id=&amp;#39;binary1&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;            &amp;lt;Feature&lt;br/&gt;                Id=&amp;#39;Environment&amp;#39;&lt;br/&gt;                Title=&amp;#39;PATH Environment Variable&amp;#39;&lt;br/&gt;                Description=&amp;#39;Add the install location of the [ProductName] executable to the PATH system environment variable. This allows the [ProductName] executable to be called from any location.&amp;#39;&lt;br/&gt;                Level=&amp;#39;1&amp;#39;&lt;br/&gt;                Absent=&amp;#39;allow&amp;#39;&amp;gt;&lt;br/&gt;                &amp;lt;ComponentRef Id=&amp;#39;Path&amp;#39;/&amp;gt;&lt;br/&gt;            &amp;lt;/Feature&amp;gt;&lt;br/&gt;        &amp;lt;/Feature&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;SetProperty Id=&amp;#39;ARPINSTALLLOCATION&amp;#39; Value=&amp;#39;[APPLICATIONFOLDER]&amp;#39; After=&amp;#39;CostFinalize&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the following `Icon` and `Property` tags to change the product icon.&lt;br/&gt;&lt;br/&gt;          The product icon is the graphic that appears in the Add/Remove&lt;br/&gt;          Programs control panel for the application.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;Icon Id=&amp;#39;ProductICO&amp;#39; SourceFile=&amp;#39;wix\Product.ico&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;Property Id=&amp;#39;ARPPRODUCTICON&amp;#39; Value=&amp;#39;ProductICO&amp;#39; /&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Property Id=&amp;#39;ARPHELPLINK&amp;#39; Value=&amp;#39;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash&amp;#39;/&amp;gt&#34;&gt;https://github.com/gnostr-org/get_file_hash&amp;#39;/&amp;gt&lt;/a&gt;;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;UI&amp;gt;&lt;br/&gt;            &amp;lt;UIRef Id=&amp;#39;WixUI_FeatureTree&amp;#39;/&amp;gt;&lt;br/&gt;            &lt;br/&gt;            &amp;lt;!--&lt;br/&gt;              Enabling the EULA dialog in the installer is a three step process:&lt;br/&gt;&lt;br/&gt;                1. Comment out or remove the two `Publish` tags that follow the&lt;br/&gt;                   `WixVariable` tag.&lt;br/&gt;                2. Uncomment the `&amp;lt;WixVariable Id=&amp;#39;WixUILicenseRtf&amp;#39; Value=&amp;#39;Path\to\Eula.rft&amp;#39;&amp;gt;` tag further down&lt;br/&gt;                3. Replace the `Value` attribute of the `WixVariable` tag with&lt;br/&gt;                   the path to a RTF file that will be used as the EULA and&lt;br/&gt;                   displayed in the license agreement dialog.&lt;br/&gt;            --&amp;gt;&lt;br/&gt;            &amp;lt;Publish Dialog=&amp;#39;WelcomeDlg&amp;#39; Control=&amp;#39;Next&amp;#39; Event=&amp;#39;NewDialog&amp;#39; Value=&amp;#39;CustomizeDlg&amp;#39; Order=&amp;#39;99&amp;#39;&amp;gt;1&amp;lt;/Publish&amp;gt;&lt;br/&gt;            &amp;lt;Publish Dialog=&amp;#39;CustomizeDlg&amp;#39; Control=&amp;#39;Back&amp;#39; Event=&amp;#39;NewDialog&amp;#39; Value=&amp;#39;WelcomeDlg&amp;#39; Order=&amp;#39;99&amp;#39;&amp;gt;1&amp;lt;/Publish&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;/UI&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Enabling the EULA dialog in the installer requires uncommenting&lt;br/&gt;          the following `WixUILicenseRTF` tag and changing the `Value`&lt;br/&gt;          attribute.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!-- &amp;lt;WixVariable Id=&amp;#39;WixUILicenseRtf&amp;#39; Value=&amp;#39;Relative\Path\to\Eula.rtf&amp;#39;/&amp;gt; --&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the next `WixVariable` tag to customize the installer&amp;#39;s&lt;br/&gt;          Graphical User Interface (GUI) and add a custom banner image across&lt;br/&gt;          the top of each screen. See the WiX Toolset documentation for details&lt;br/&gt;          about customization.&lt;br/&gt;&lt;br/&gt;          The banner BMP dimensions are 493 x 58 pixels.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;WixVariable Id=&amp;#39;WixUIBannerBmp&amp;#39; Value=&amp;#39;wix\Banner.bmp&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the next `WixVariable` tag to customize the installer&amp;#39;s&lt;br/&gt;          Graphical User Interface (GUI) and add a custom image to the first&lt;br/&gt;          dialog, or screen. See the WiX Toolset documentation for details about&lt;br/&gt;          customization.&lt;br/&gt;&lt;br/&gt;          The dialog BMP dimensions are 493 x 312 pixels.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;WixVariable Id=&amp;#39;WixUIDialogBmp&amp;#39; Value=&amp;#39;wix\Dialog.bmp&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;    &amp;lt;/Product&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;/Wix&amp;gt;&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:48:38Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqszzyy4qxl8s92re897479h4nlh0w6frr43qs8t9w5cksv0sqw2usczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj2rs38d</id>
    
      <title type="html">use std::process::Command; use std::fs; use sha2::{Digest, ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqszzyy4qxl8s92re897479h4nlh0w6frr43qs8t9w5cksv0sqw2usczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj2rs38d" />
    <content type="html">
      use std::process::Command;&lt;br/&gt;use std::fs;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn calculate_sha256(file_path: &amp;amp;str) -&amp;gt; String {&lt;br/&gt;    let content = fs::read(file_path).expect(&amp;#34;Unable to read file&amp;#34;);&lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(&amp;amp;content);&lt;br/&gt;    hasher.finalize()&lt;br/&gt;        .iter()&lt;br/&gt;        .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;        .collect()&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[test]&lt;br/&gt;fn test_get_file_hash_binary_no_features() {&lt;br/&gt;    let output = Command::new(&amp;#34;cargo&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;run&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--bin&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;get_file_hash&amp;#34;)&lt;br/&gt;        .output()&lt;br/&gt;        .expect(&amp;#34;Failed to execute command&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let stdout = String::from_utf8_lossy(&amp;amp;output.stdout);&lt;br/&gt;    let stderr = String::from_utf8_lossy(&amp;amp;output.stderr);&lt;br/&gt;&lt;br/&gt;    // Assert that the command ran successfully&lt;br/&gt;    assert!(output.status.success(), &amp;#34;Command failed with stderr: {}&amp;#34;, stderr);&lt;br/&gt;&lt;br/&gt;    // Manually calculate the hash of the binary&amp;#39;s source file&lt;br/&gt;    let expected_hash = calculate_sha256(&amp;#34;src/bin/get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains the correct hash&lt;br/&gt;    // Check for the raw hash first&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash), &amp;#34;Output did not contain raw expected hash. Expected: {}, Actual: {}&amp;#34;, expected_hash, stdout);&lt;br/&gt;&lt;br/&gt;    // Then check for the formatted string, including backticks&lt;br/&gt;    // Use a regex-like check for more flexibility with newlines if needed, or refine to exact match&lt;br/&gt;    let expected_hash_line = format!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, expected_hash);&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash_line), &amp;#34;Output did not contain expected hash line. Expected line: {}, Actual: {}&amp;#34;, expected_hash_line, stdout);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    assert!(stdout.contains(&amp;#34;Integrity Verified.&amp;#34;), &amp;#34;Output did not contain &amp;#39;Integrity Verified.&amp;#39;. stdout: {}&amp;#34;, stdout);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Output from get_file_hash binary (no features):&lt;br/&gt;{}&amp;#34;, stdout);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[test]&lt;br/&gt;fn test_get_file_hash_binary_with_nostr_feature() {&lt;br/&gt;    let output = Command::new(&amp;#34;cargo&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;run&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--bin&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;get_file_hash&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--features&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;nostr&amp;#34;)&lt;br/&gt;        .output()&lt;br/&gt;        .expect(&amp;#34;Failed to execute command&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let stdout = String::from_utf8_lossy(&amp;amp;output.stdout);&lt;br/&gt;    let stderr = String::from_utf8_lossy(&amp;amp;output.stderr);&lt;br/&gt;&lt;br/&gt;    // Assert that the command ran successfully&lt;br/&gt;    assert!(output.status.success(), &amp;#34;Command failed with stderr: {}&amp;#34;, stderr);&lt;br/&gt;&lt;br/&gt;    // Manually calculate the hash of the binary&amp;#39;s source file&lt;br/&gt;    let expected_hash = calculate_sha256(&amp;#34;src/bin/get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains the correct hash&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash), &amp;#34;Output did not contain raw expected hash. Expected: {}, Actual: {}&amp;#34;, expected_hash, stdout);&lt;br/&gt;&lt;br/&gt;    // Then check for the formatted string, including backticks&lt;br/&gt;    let expected_hash_line = format!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, expected_hash);&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash_line), &amp;#34;Output did not contain expected hash line. Expected line: {}, Actual: {}&amp;#34;, expected_hash_line, stdout);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    assert!(stdout.contains(&amp;#34;Integrity Verified.&amp;#34;), &amp;#34;Output did not contain &amp;#39;Integrity Verified.&amp;#39;. stdout: {}&amp;#34;, stdout);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Output from get_file_hash binary (with nostr feature):&lt;br/&gt;{}&amp;#34;, stdout);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:48:26Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsfx78cgfdfhpvta693sdjg3spf3vq754fxgqvz3qt28rvyd5xr4nczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjlkglsw</id>
    
      <title type="html">//! A crate providing the `get_file_hash!` procedural macro. //! ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsfx78cgfdfhpvta693sdjg3spf3vq754fxgqvz3qt28rvyd5xr4nczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjlkglsw" />
    <content type="html">
      //! A crate providing the `get_file_hash!` procedural macro.&lt;br/&gt;//!&lt;br/&gt;//! This macro allows you to compute the SHA-256 hash of a file at compile time,&lt;br/&gt;//! embedding the resulting hash string directly into your Rust executable.&lt;br/&gt;&lt;br/&gt;pub use get_file_hash_core::get_file_hash;&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `build.rs` at the time of compilation.&lt;br/&gt;pub const BUILD_HASH: &amp;amp;str = env!(&amp;#34;BUILD_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `Cargo.toml` at the time of compilation.&lt;br/&gt;pub const CARGO_TOML_HASH: &amp;amp;str = env!(&amp;#34;CARGO_TOML_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `src/lib.rs` at the time of compilation.&lt;br/&gt;pub const LIB_HASH: &amp;amp;str = env!(&amp;#34;LIB_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The name of the package as specified in Cargo.toml.&lt;br/&gt;pub const CARGO_PKG_NAME: &amp;amp;str = env!(&amp;#34;CARGO_PKG_NAME&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The version of the package as specified in Cargo.toml.&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;/// The git commit hash of the repository at the time of compilation.&lt;br/&gt;pub const GIT_COMMIT_HASH: &amp;amp;str = env!(&amp;#34;GIT_COMMIT_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;/// The git branch of the repository at the time of compilation.&lt;br/&gt;pub const GIT_BRANCH: &amp;amp;str = env!(&amp;#34;GIT_BRANCH&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(test)]&lt;br/&gt;mod tests {&lt;br/&gt;    use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;    use super::*;&lt;br/&gt;&lt;br/&gt;    /// Verifies that the exported CARGO_TOML_HASH is not empty.&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_injected_hash_exists() {&lt;br/&gt;        assert!(!BUILD_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified build.rs Hash:&lt;br/&gt;{}&amp;#34;, BUILD_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_TOML_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Cargo.toml Hash:&lt;br/&gt;{}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!LIB_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified src/lib.rs Hash:\n{}&amp;#34;, LIB_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_PKG_NAME.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Package Name:\n{}&amp;#34;, CARGO_PKG_NAME);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_PKG_VERSION.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Package Version:\n{}&amp;#34;, CARGO_PKG_VERSION);&lt;br/&gt;&lt;br/&gt;        #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;        {&lt;br/&gt;            assert!(!GIT_COMMIT_HASH.is_empty());&lt;br/&gt;            println!(&amp;#34;Verified Git Commit Hash:\n{}&amp;#34;, GIT_COMMIT_HASH);&lt;br/&gt;&lt;br/&gt;            assert!(!GIT_BRANCH.is_empty());&lt;br/&gt;            println!(&amp;#34;Verified Git Branch:\n{}&amp;#34;, GIT_BRANCH);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// Tests that the `get_file_hash!` macro correctly computes the SHA-256&lt;br/&gt;    /// hash of `lib.rs` and that it matches a manually computed hash of the&lt;br/&gt;    /// same file.&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_get_lib_hash() {&lt;br/&gt;        let file_content = include_bytes!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let mut hasher = Sha256::new();&lt;br/&gt;        hasher.update(file_content);&lt;br/&gt;        let expected_hash = hasher&lt;br/&gt;            .finalize()&lt;br/&gt;            .iter()&lt;br/&gt;            .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;            .collect::&amp;lt;String&amp;gt;();&lt;br/&gt;&lt;br/&gt;        let actual_hash = get_file_hash!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;        assert_eq!(actual_hash, expected_hash);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:48:14Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsdmv7zfxf09ts7qpqcg4xkpy2e40j9alc2u8neggj5m0xme7u7wjczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjy0ye3p</id>
    
      <title type="html">Relay URL,Latitude,Longitude wot.nostr.party,36.1627,-86.7816 ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsdmv7zfxf09ts7qpqcg4xkpy2e40j9alc2u8neggj5m0xme7u7wjczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjy0ye3p" />
    <content type="html">
      Relay URL,Latitude,Longitude&lt;br/&gt;wot.nostr.party,36.1627,-86.7816&lt;br/&gt;nostr.simplex.icu,50.1109,8.68213&lt;br/&gt;relay.snort.social,53.3498,-6.26031&lt;br/&gt;nostr.stakey.net,52.3676,4.90414&lt;br/&gt;relay.mccormick.cx,52.3563,4.95714&lt;br/&gt;nostr.overmind.lol,43.6532,-79.3832&lt;br/&gt;nostriches.club,43.6532,-79.3832&lt;br/&gt;kanagrovv-pyramid.kozow.com,43.4305,-83.9638&lt;br/&gt;relay.toastr.net,40.8054,-74.0241&lt;br/&gt;relay.primal.net,43.6532,-79.3832&lt;br/&gt;r.bitcoinhold.net,43.6532,-79.3832&lt;br/&gt;wot.dtonon.com,43.6532,-79.3832&lt;br/&gt;santo.iguanatech.net,40.8302,-74.1299&lt;br/&gt;relay2.ngengine.org,43.6532,-79.3832&lt;br/&gt;nostr.oxtr.dev,50.4754,12.3683&lt;br/&gt;simplex.icu,50.1109,8.68213&lt;br/&gt;bitchat.nostr1.com,38.6327,-90.1961&lt;br/&gt;relay.nostu.be,40.4167,-3.70329&lt;br/&gt;nostr.mifen.me,43.6532,-79.3832&lt;br/&gt;relay.vantis.ninja,43.6532,-79.3832&lt;br/&gt;nostr-kyomu-haskell.onrender.com,37.7775,-122.397&lt;br/&gt;nostr-relay.amethyst.name,39.0067,-77.4291&lt;br/&gt;relay.bitcoindistrict.org,43.6532,-79.3832&lt;br/&gt;nos.xmark.cc,50.6924,3.20113&lt;br/&gt;relay01.lnfi.network,35.6764,139.65&lt;br/&gt;nostr-dev.wellorder.net,45.5201,-122.99&lt;br/&gt;nostr.rblb.it,43.7094,10.6582&lt;br/&gt;offchain.pub,39.1585,-94.5728&lt;br/&gt;wot.nostr.place,32.7767,-96.797&lt;br/&gt;fanfares.nostr1.com,38.6327,-90.1961&lt;br/&gt;ephemeral.snowflare.cc,43.6532,-79.3832&lt;br/&gt;relay.visionfusen.org,43.6532,-79.3832&lt;br/&gt;nostr.carroarmato0.be,51.0368,3.21186&lt;br/&gt;social.amanah.eblessing.co,48.1046,11.6002&lt;br/&gt;relay.cyphernomad.com,60.4032,25.0321&lt;br/&gt;nostr-rs-relay-qj1h.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ngengine.org,43.6532,-79.3832&lt;br/&gt;relay.nosto.re,51.1792,5.89444&lt;br/&gt;rusty-uat.siberian-albacore.ts.net:8443,35.6764,139.65&lt;br/&gt;nostr.luisschwab.net,43.6532,-79.3832&lt;br/&gt;nostr.aruku.ovh,1.27994,103.849&lt;br/&gt;srtrelay.c-stellar.net,43.6532,-79.3832&lt;br/&gt;nostr.tagomago.me,3.139,101.687&lt;br/&gt;relay.threenine.services,51.5222,-0.62916&lt;br/&gt;nostr.robosats.org,64.1476,-21.9392&lt;br/&gt;nostr.2b9t.xyz,34.0549,-118.243&lt;br/&gt;strfry.apps3.slidestr.net,40.4167,-3.70329&lt;br/&gt;kitchen.zap.cooking,43.6532,-79.3832&lt;br/&gt;relay.homeinhk.xyz,45.5152,-122.678&lt;br/&gt;relay.seq1.net,43.6532,-79.3832&lt;br/&gt;relay.bornheimer.app,50.1109,8.68213&lt;br/&gt;relay.vrtmrz.net,43.6532,-79.3832&lt;br/&gt;nostr.red5d.dev,43.6532,-79.3832&lt;br/&gt;relay-freeharmonypeople.space,38.7223,-9.13934&lt;br/&gt;aaa-api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;dev.relay.edufeed.org,49.4521,11.0767&lt;br/&gt;nostr.myshosholoza.co.za,52.3913,4.66545&lt;br/&gt;nostr.plantroon.com,50.1013,8.62643&lt;br/&gt;wot.dergigi.com,64.1476,-21.9392&lt;br/&gt;npub1spxdug4m3y24hpx5crm0el4zhkk0wafs8kp6m0xu0wecygqej2xqq8gyhx.fips.network,43.6532,-79.3832&lt;br/&gt;nostrelay.circum.space,52.3676,4.90414&lt;br/&gt;relay.dreamith.to,43.6532,-79.3832&lt;br/&gt;relay.nostriches.club,43.6532,-79.3832&lt;br/&gt;nostr-relayrs.gateway.in.th,15.5163,103.194&lt;br/&gt;nostr.chrissexton.org,43.6532,-79.3832&lt;br/&gt;relay.flashapp.me,43.652,-79.3633&lt;br/&gt;nostr-relay-1.trustlessenterprise.com,43.6532,-79.3832&lt;br/&gt;strfry.shock.network,39.0438,-77.4874&lt;br/&gt;relay.snotr.nl:49999,52.0195,4.42946&lt;br/&gt;spatia-arcana.com,34.0362,-118.443&lt;br/&gt;nostr.computingcache.com,34.0356,-118.442&lt;br/&gt;nostr.self-determined.de,53.5,10.25&lt;br/&gt;relay.sharegap.net,43.6532,-79.3832&lt;br/&gt;spookstr2.nostr1.com,38.6327,-90.1961&lt;br/&gt;v-relay.d02.vrtmrz.net,34.6937,135.502&lt;br/&gt;bridge.tagomago.me,3.139,101.687&lt;br/&gt;antiprimal.net,43.6532,-79.3832&lt;br/&gt;relay.nostrdice.com,-33.8688,151.209&lt;br/&gt;purpura.cloud,43.6532,-79.3832&lt;br/&gt;espelho.girino.org,43.6532,-79.3832&lt;br/&gt;relay.mostro.network,40.8302,-74.1299&lt;br/&gt;temp.iris.to,43.6532,-79.3832&lt;br/&gt;pyramid.self-determined.de,53.5,10.25&lt;br/&gt;relay.jeffg.fyi,43.6532,-79.3832&lt;br/&gt;nostr.aruku.kro.kr,37.3589,127.115&lt;br/&gt;chat-relay.zap-work.com,43.6532,-79.3832&lt;br/&gt;relay.islandbitcoin.com,12.8498,77.6545&lt;br/&gt;nostr.zoracle.org,45.6018,-121.185&lt;br/&gt;relay-dev.satlantis.io,40.8302,-74.1299&lt;br/&gt;relay.earthly.city,34.0362,-118.443&lt;br/&gt;speakeasy.cellar.social,49.4543,11.0746&lt;br/&gt;relay.bnos.space,43.6532,-79.3832&lt;br/&gt;relay.henryxplace.eu.org:9988,31.2304,121.474&lt;br/&gt;relay.bitmacro.cloud,43.6532,-79.3832&lt;br/&gt;nostr.thebiglake.org,32.71,-96.6745&lt;br/&gt;relay.lab.rytswd.com,49.4543,11.0746&lt;br/&gt;nostr.nadajnik.org,50.1109,8.68213&lt;br/&gt;relay.evanverma.com,40.8302,-74.1299&lt;br/&gt;relay2.angor.io,48.1046,11.6002&lt;br/&gt;prl.plus,55.7628,37.5983&lt;br/&gt;myvoiceourstory.org,37.3598,-121.981&lt;br/&gt;relay.arx-ccn.com,50.4754,12.3683&lt;br/&gt;wot.sudocarlos.com,43.6532,-79.3832&lt;br/&gt;relayrs.notoshi.win,43.6532,-79.3832&lt;br/&gt;nostrcity-club.fly.dev,48.8575,2.35138&lt;br/&gt;relay.tagayasu.xyz,45.4215,-75.6972&lt;br/&gt;nostr.blankfors.se,60.1699,24.9384&lt;br/&gt;nrs-01.darkcloudarcade.com,39.1008,-94.5811&lt;br/&gt;relay.lightning.pub,39.0438,-77.4874&lt;br/&gt;nostr-02.yakihonne.com,1.32123,103.695&lt;br/&gt;relay.nostrverse.net,43.6532,-79.3832&lt;br/&gt;nostr.wecsats.io,43.6532,-79.3832&lt;br/&gt;relay.illuminodes.com,47.6062,-122.332&lt;br/&gt;api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;nostr-relay.psfoundation.info,39.0438,-77.4874&lt;br/&gt;relay.samt.st,40.8302,-74.1299&lt;br/&gt;nostr-relay.cbrx.io,43.6532,-79.3832&lt;br/&gt;inbox.mycelium.social,38.627,-90.1994&lt;br/&gt;relay.anmore.me,49.281,-123.117&lt;br/&gt;no.str.cr,10.074,-84.2155&lt;br/&gt;nstr.a0a1.space,52.3563,4.95714&lt;br/&gt;relay.typedcypher.com,51.5072,-0.127586&lt;br/&gt;relay.bitmacro.pro,43.6532,-79.3832&lt;br/&gt;relay.nostrzh.org,43.6532,-79.3832&lt;br/&gt;ynostr.yael.at,60.1699,24.9384&lt;br/&gt;nostr-relay.zeabur.app,25.0797,121.234&lt;br/&gt;dynasty.libretechsystems.xyz,55.4724,9.87335&lt;br/&gt;nostr.bitcoiner.social,47.6743,-117.112&lt;br/&gt;nostr.girino.org,43.6532,-79.3832&lt;br/&gt;nostr2.girino.org,43.6532,-79.3832&lt;br/&gt;nostr-verified.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.fundstr.me,42.3601,-71.0589&lt;br/&gt;relay.mapboss.co.th,13.7234,100.784&lt;br/&gt;relay.qstr.app,51.5072,-0.127586&lt;br/&gt;nostr-rs-relay-ishosta.phamthanh.me,43.6532,-79.3832&lt;br/&gt;relay.klabo.world,47.674,-122.122&lt;br/&gt;relay.minibolt.info,43.6532,-79.3832&lt;br/&gt;x.kojira.io,43.6532,-79.3832&lt;br/&gt;relay-dev.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostriot.com,41.5695,-83.9786&lt;br/&gt;relayone.soundhsa.com,39.1008,-94.5811&lt;br/&gt;nr.yay.so,46.2126,6.1154&lt;br/&gt;relay.bithome.site,52.3563,4.95714&lt;br/&gt;relay.damus.io,43.6532,-79.3832&lt;br/&gt;nostr.mikoshi.de,50.1109,8.68213&lt;br/&gt;nostr.defucc.me,50.1109,8.68213&lt;br/&gt;relay.malxte.de,52.52,13.405&lt;br/&gt;relay.orangepill.ovh,49.1689,-0.358841&lt;br/&gt;bbw-nostr.xyz,41.5284,-87.4237&lt;br/&gt;kasztanowa.bieda.it,43.6532,-79.3832&lt;br/&gt;bitcoiner.social,47.6743,-117.112&lt;br/&gt;relay.lacompagniemaximus.com,45.3147,-73.8785&lt;br/&gt;relay.mostr.pub,43.6532,-79.3832&lt;br/&gt;relay.lanavault.space,60.1699,24.9384&lt;br/&gt;kotukonostr.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ditto.pub,43.6532,-79.3832&lt;br/&gt;relay.erybody.com,41.4513,-81.7021&lt;br/&gt;nostr.dlcdevkit.com,40.0992,-83.1141&lt;br/&gt;ribo.us.nostria.app,41.5868,-93.625&lt;br/&gt;relay.paulstephenborile.com,49.4543,11.0746&lt;br/&gt;testnet-relay.samt.st,40.8302,-74.1299&lt;br/&gt;relay.purplefrog.cloud,35.6916,139.768&lt;br/&gt;relay.agorist.space,52.3734,4.89406&lt;br/&gt;nostr-relay.zimage.com,34.0549,-118.243&lt;br/&gt;nostr.azzamo.net,52.2633,21.0283&lt;br/&gt;strfry.elswa-dev.online,50.1109,8.68213&lt;br/&gt;wot.shaving.kiwi,43.6532,-79.3832&lt;br/&gt;okn.czas.plus,50.1109,8.68213&lt;br/&gt;bcast.seutoba.com.br,43.6532,-79.3832&lt;br/&gt;relay.sigit.io,50.4754,12.3683&lt;br/&gt;syb.lol,34.0549,-118.243&lt;br/&gt;relay.libernet.app,43.6532,-79.3832&lt;br/&gt;relay.angor.io,48.1046,11.6002&lt;br/&gt;relay.staging.commonshub.brussels,49.4543,11.0746&lt;br/&gt;strfry.atlantislabs.space,43.6532,-79.3832&lt;br/&gt;nostr.wom.wtf,43.6532,-79.3832&lt;br/&gt;nostrride.io,37.3986,-121.964&lt;br/&gt;nostr.dpinkerton.com,39.1008,-94.5811&lt;br/&gt;r.0kb.io,32.789,-96.7989&lt;br/&gt;nostr.hekster.org,37.3986,-121.964&lt;br/&gt;satsage.xyz,37.3986,-121.964&lt;br/&gt;nostr.islandarea.net,35.4669,-97.6473&lt;br/&gt;ve.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.openfarmtools.org,60.1699,24.9384&lt;br/&gt;top.testrelay.top,43.6532,-79.3832&lt;br/&gt;relay-rpi.edufeed.org,49.4521,11.0767&lt;br/&gt;pyramid.cult.cash,32.9483,-96.7299&lt;br/&gt;relay.edino.net,56.6268,47.9193&lt;br/&gt;nostr.snowbla.de,60.1699,24.9384&lt;br/&gt;relay.wavefunc.live,39.7392,-104.99&lt;br/&gt;tenex.chat,50.4754,12.3683&lt;br/&gt;relay.getsafebox.app,43.6532,-79.3832&lt;br/&gt;nostr.bond,50.1109,8.68213&lt;br/&gt;nostrelites.org,41.8781,-87.6298&lt;br/&gt;relay.plebeian.market,50.1109,8.68213&lt;br/&gt;relay.laantungir.net,-19.4692,-42.5315&lt;br/&gt;relay.decentnewsroom.com,50.4754,12.3683&lt;br/&gt;nostr-relay.nextblockvending.com,47.2343,-119.853&lt;br/&gt;relay.spacetomatoes.net,42.3601,-71.0589&lt;br/&gt;nostrbtc.com,43.6532,-79.3832&lt;br/&gt;relay.puresignal.news,43.6532,-79.3832&lt;br/&gt;relay-testnet.k8s.layer3.news,37.3387,-121.885&lt;br/&gt;relay.binaryrobot.com,43.6532,-79.3832&lt;br/&gt;relay.wavlake.com,41.2619,-95.8608&lt;br/&gt;inbox.scuba323.com,40.8218,-74.45&lt;br/&gt;nostr.spaceshell.xyz,43.6532,-79.3832&lt;br/&gt;relay.nostr.place,32.7767,-96.797&lt;br/&gt;holland-excited-charming-experiencing.trycloudflare.com,43.6532,-79.3832&lt;br/&gt;theoutpost.life,64.1476,-21.9392&lt;br/&gt;relay.fckstate.net,59.3293,18.0686&lt;br/&gt;bcast.girino.org,43.6532,-79.3832&lt;br/&gt;discovery.us.nostria.app,52.3676,4.90414&lt;br/&gt;relay.bullishbounty.com,43.6532,-79.3832&lt;br/&gt;nostr.88mph.life,51.5072,-0.127586&lt;br/&gt;nostr.tadryanom.me,43.6532,-79.3832&lt;br/&gt;nostr.sathoarder.com,48.5734,7.75211&lt;br/&gt;relay.nostr.net,43.6532,-79.3832&lt;br/&gt;zw.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.internationalright-wing.org,-22.5022,-48.7114&lt;br/&gt;nostr.vulpem.com,49.4543,11.0746&lt;br/&gt;wot.codingarena.top,50.4754,12.3683&lt;br/&gt;reraw.pbla2fish.cc,43.6532,-79.3832&lt;br/&gt;plebchain.club,43.6532,-79.3832&lt;br/&gt;orly-relay.imwald.eu,48.8575,2.35138&lt;br/&gt;relay.satnam.pub,43.6532,-79.3832&lt;br/&gt;cs-relay.nostrdev.com,50.4754,12.3683&lt;br/&gt;schnorr.me,43.6532,-79.3832&lt;br/&gt;nostr-relay.online,43.6532,-79.3832&lt;br/&gt;relay.routstr.com,43.6532,-79.3832&lt;br/&gt;relay.ohstr.com,43.6532,-79.3832&lt;br/&gt;relay.lanacoin-eternity.com,40.8302,-74.1299&lt;br/&gt;wot.nostr.net,43.6532,-79.3832&lt;br/&gt;nostr.ps1829.com,33.8851,130.883&lt;br/&gt;yabu.me,35.6092,139.73&lt;br/&gt;soloco.nl,43.6532,-79.3832&lt;br/&gt;librerelay.aaroniumii.com,43.6532,-79.3832&lt;br/&gt;relay.mmwaves.de,48.8575,2.35138&lt;br/&gt;relay.artx.market,43.6548,-79.3885&lt;br/&gt;nostr.jerrynya.fun,31.2304,121.474&lt;br/&gt;relay-arg.zombi.cloudrodion.com,1.35208,103.82&lt;br/&gt;relay.edufeed.org,49.4521,11.0767&lt;br/&gt;discovery.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.layer.systems,49.0291,8.35695&lt;br/&gt;nostr-rs-relay.dev.fedibtc.com,39.0438,-77.4874&lt;br/&gt;relay.0xchat.com,43.6532,-79.3832&lt;br/&gt;nos.lol,50.4754,12.3683&lt;br/&gt;lightning.red,53.3498,-6.26031&lt;br/&gt;slick.mjex.me,39.0418,-77.4744&lt;br/&gt;relay.boredvictor.xyz,41.3888,2.15899&lt;br/&gt;nostr.rtvslawenia.com,49.4543,11.0746&lt;br/&gt;relay.mitchelltribe.com,39.0438,-77.4874&lt;br/&gt;nostr.4rs.nl,49.0291,8.35696&lt;br/&gt;relay.olas.app,50.4754,12.3683&lt;br/&gt;memlay.v0l.io,53.3498,-6.26031&lt;br/&gt;nostr-01.yakihonne.com,1.29524,103.79&lt;br/&gt;relay.satmaxt.xyz,43.6532,-79.3832&lt;br/&gt;nostrcheck.tnsor.network,43.6532,-79.3832&lt;br/&gt;relay.guggero.org,46.0037,8.95105&lt;br/&gt;ai.techunder.tech:56711,22.5429,114.06&lt;br/&gt;premium.primal.net,43.6532,-79.3832&lt;br/&gt;nostr.tac.lol,47.4748,-122.273&lt;br/&gt;relay.zone667.com,60.1699,24.9384&lt;br/&gt;nostr-relay.gateway.in.th,15.5163,103.194&lt;br/&gt;vault.iris.to,43.6532,-79.3832&lt;br/&gt;strfry.bonsai.com,37.8716,-122.273&lt;br/&gt;ribo.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.tapestry.ninja,40.8054,-74.0241&lt;br/&gt;relay.dwadziesciajeden.pl,52.2297,21.0122&lt;br/&gt;relay.satlantis.io,32.8769,-80.0114&lt;br/&gt;nostr.pbfs.io,50.4754,12.3683&lt;br/&gt;freelay.sovbit.host,64.1476,-21.9392&lt;br/&gt;articles.layer3.news,37.3387,-121.885&lt;br/&gt;nostr.na.social,43.6532,-79.3832&lt;br/&gt;relay.fountain.fm,43.6532,-79.3832&lt;br/&gt;dev.relay.stream,43.6532,-79.3832&lt;br/&gt;nostr.n7ekb.net,36.1527,-95.9902&lt;br/&gt;relay5.bitransfer.org,43.6532,-79.3832&lt;br/&gt;relay.og.coop,43.6532,-79.3832&lt;br/&gt;nostr-server-production.up.railway.app,45.5019,-73.5674&lt;br/&gt;bucket.coracle.social,37.7775,-122.397&lt;br/&gt;relay.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostr-check.me,43.6532,-79.3832&lt;br/&gt;nostr.faultables.net,43.6532,-79.3832&lt;br/&gt;strfry.openhoofd.nl,51.9229,4.40833&lt;br/&gt;nostr.rblb.it:7777,43.7094,10.6582&lt;br/&gt;relay.nostrcheck.me,43.6532,-79.3832&lt;br/&gt;0x-nostr-relay.fly.dev,48.8575,2.35138&lt;br/&gt;nostr.thalheim.io,60.1699,24.9384&lt;br/&gt;relay-nl.zombi.cloudrodion.com,50.8943,6.06237&lt;br/&gt;relay.shadowbip.com,51.5072,-0.127586&lt;br/&gt;nostr-relay.corb.net,38.8353,-104.822&lt;br/&gt;purplerelay.com,43.6532,-79.3832&lt;br/&gt;nostr-pub.wellorder.net,45.5201,-122.99&lt;br/&gt;herbstmeister.com,34.0549,-118.243&lt;br/&gt;nostrcheck.me,43.6532,-79.3832&lt;br/&gt;pyramid.nostr.technology,52.3947,4.66399&lt;br/&gt;nostr.spicyz.io,43.6532,-79.3832&lt;br/&gt;nrs-02.darkcloudarcade.com,39.9526,-75.1652&lt;br/&gt;nestr.nedao.ch,47.0151,6.98832&lt;br/&gt;nostr.nodesmap.com,59.3327,18.0656&lt;br/&gt;nittom.nostr1.com,38.6327,-90.1961&lt;br/&gt;public.crostr.com,43.6532,-79.3832&lt;br/&gt;relay.cypherflow.ai,48.8575,2.35138&lt;br/&gt;nostr.bitczat.pl,60.1699,24.9384&lt;br/&gt;relayone.geektank.ai,39.1008,-94.5811&lt;br/&gt;testrelay.era21.space,43.6532,-79.3832&lt;br/&gt;relay.npubhaus.com,43.6532,-79.3832&lt;br/&gt;relay.bitmacro.io,48.8566,2.35222&lt;br/&gt;nostr.data.haus,50.4754,12.3683&lt;br/&gt;relay.credenso.cafe,43.3601,-80.3127&lt;br/&gt;relay.ru.ac.th,13.7607,100.627&lt;br/&gt;relay-fra.zombi.cloudrodion.com,48.8566,2.35222&lt;br/&gt;nostr.chaima.info,50.1109,8.68213&lt;br/&gt;nostr.mom,50.4754,12.3683
    </content>
    <updated>2026-04-04T01:48:01Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsf5tz78gqrwwsp7tk7gvekz9yl43ary9zl7fseyacmus73hg6lf0qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjll5lul</id>
    
      <title type="html">#![cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsf5tz78gqrwwsp7tk7gvekz9yl43ary9zl7fseyacmus73hg6lf0qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjll5lul" />
    <content type="html">
      #![cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;use frost::keys::PublicKeyPackage;&lt;br/&gt;use frost::round2::SignatureShare;&lt;br/&gt;use frost::SigningPackage;&lt;br/&gt;use hex;&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;use sha2::Sha256;&lt;br/&gt;use serde_json;&lt;br/&gt;use sha2::Digest;&lt;br/&gt;&lt;br/&gt;pub fn process_relay_share(&lt;br/&gt;    relay_payload_hex: &amp;amp;str,&lt;br/&gt;    signer_id_u16: u16,&lt;br/&gt;    _signing_package: &amp;amp;SigningPackage,&lt;br/&gt;    _pubkey_package: &amp;amp;PublicKeyPackage,&lt;br/&gt;) -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    // In a real scenario, this function would deserialize the share, perform&lt;br/&gt;    // individual verification, and store it for aggregation.&lt;br/&gt;    // For this example, we&amp;#39;ll just acknowledge receipt.&lt;br/&gt;    let _share_bytes = hex::decode(relay_payload_hex)?;&lt;br/&gt;    let _share = SignatureShare::deserialize(&amp;amp;_share_bytes)?;&lt;br/&gt;    let _identifier = frost::Identifier::try_from(signer_id_u16)?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;✅ Share from Signer {} processed (simplified).&amp;#34;, signer_id_u16);&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;pub fn simulate_frost_mailbox_coordinator() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (2, 2);&lt;br/&gt;&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    let signer1_id = frost::Identifier::try_from(1 as u16)?;&lt;br/&gt;    let key_package1: frost::keys::KeyPackage = shares[&amp;amp;signer1_id].clone().try_into()?;&lt;br/&gt;    let signer2_id = frost::Identifier::try_from(2 as u16)?;&lt;br/&gt;    let key_package2: frost::keys::KeyPackage = shares[&amp;amp;signer2_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    let message = b&amp;#34;BIP-64MOD: Anchor Data Proposal v1&amp;#34;;&lt;br/&gt;&lt;br/&gt;    let (nonces1, comms1) = frost::round1::commit(key_package1.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    let (nonces2, comms2) = frost::round1::commit(key_package2.signing_share(), &amp;amp;mut rng);&lt;br/&gt;&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    session_commitments.insert(signer1_id, comms1);&lt;br/&gt;    session_commitments.insert(signer2_id, comms2);&lt;br/&gt;&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments.clone(), message);&lt;br/&gt;&lt;br/&gt;    let share1 = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces1, &amp;amp;key_package1)?;&lt;br/&gt;    let share1_hex = hex::encode(share1.serialize());&lt;br/&gt;&lt;br/&gt;    let share2 = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces2, &amp;amp;key_package2)?;&lt;br/&gt;    let share2_hex = hex::encode(share2.serialize());&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Coordinator listening for Nostr events (simulated)...&amp;#34;);&lt;br/&gt;&lt;br/&gt;    process_relay_share(&amp;amp;share1_hex, 1_u16, &amp;amp;signing_package, &amp;amp;pubkey_package)?;&lt;br/&gt;    process_relay_share(&amp;amp;share2_hex, 2_u16, &amp;amp;signing_package, &amp;amp;pubkey_package)?;&lt;br/&gt;    println!(&amp;#34;All required shares processed. Coordinator would now aggregate.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Simulates a Signer producing a FROST signature share and preparing a Nostr event&lt;br/&gt;/// to be sent to a coordinator via a &amp;#34;mailbox&amp;#34; relay.&lt;br/&gt;///&lt;br/&gt;/// In a real ROAST setup, signers would generate their share and post it&lt;br/&gt;/// encrypted (e.g., using NIP-44) to a coordinator&amp;#39;s &amp;#34;mailbox&amp;#34; on a Nostr relay.&lt;br/&gt;/// This function demonstrates the creation of the signature share and the&lt;br/&gt;/// construction of a *simplified* Nostr event JSON.&lt;br/&gt;///&lt;br/&gt;/// # Arguments&lt;br/&gt;///&lt;br/&gt;/// * `_identifier` - The FROST identifier of the signer. (Currently unused in this specific function body).&lt;br/&gt;/// * `signing_package` - The FROST signing package received from the coordinator.&lt;br/&gt;/// * `nonces` - The signer&amp;#39;s nonces generated in Round 1.&lt;br/&gt;/// * `key_package` - The signer&amp;#39;s FROST key package.&lt;br/&gt;/// * `coordinator_pubkey` - The hex-encoded public key of the ROAST coordinator,&lt;br/&gt;///                          used to tag the Nostr event.&lt;br/&gt;///&lt;br/&gt;/// # Returns&lt;br/&gt;///&lt;br/&gt;/// A `Result` containing the JSON string of the Nostr event if successful,&lt;br/&gt;/// or a `Box&amp;lt;dyn std::error::Error&amp;gt;` if an error occurs.&lt;br/&gt;pub fn create_signer_event(&lt;br/&gt;    _identifier: frost::Identifier,&lt;br/&gt;    signing_package: &amp;amp;frost::SigningPackage,&lt;br/&gt;    nonces: &amp;amp;frost::round1::SigningNonces,&lt;br/&gt;    key_package: &amp;amp;frost::keys::KeyPackage,&lt;br/&gt;    coordinator_pubkey: &amp;amp;str, // The Hex pubkey of the ROAST coordinator&lt;br/&gt;) -&amp;gt; Result&amp;lt;String, Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;&lt;br/&gt;    // 1. Generate the partial signature share (Round 2 of FROST)&lt;br/&gt;    // This share is the core cryptographic output from the signer.&lt;br/&gt;    let share = frost::round2::sign(signing_package, nonces, key_package)?;&lt;br/&gt;    let share_bytes = share.serialize();&lt;br/&gt;    let share_hex = hex::encode(share_bytes);&lt;br/&gt;&lt;br/&gt;    // 2. Create a Session ID to tag the event&lt;br/&gt;    // This ID is derived from the signing package hash, allowing the coordinator&lt;br/&gt;    // to correlate shares belonging to the same signing session.&lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(signing_package.serialize()?);&lt;br/&gt;    let session_id = hex::encode(hasher.finalize());&lt;br/&gt;&lt;br/&gt;    // 3. Construct the Nostr Event JSON (Simplified)&lt;br/&gt;    // This JSON represents the event that a signer would post to a relay.&lt;br/&gt;    // In a production ROAST system, the &amp;#39;content&amp;#39; field (the signature share)&lt;br/&gt;    // would be encrypted for the coordinator using NIP-44.&lt;br/&gt;    let event = serde_json::json!({&lt;br/&gt;        &amp;#34;kind&amp;#34;: 4, // Example: Using Kind 4 (Private Message), though custom Kinds could be used for Sovereign Stack.&lt;br/&gt;        &amp;#34;pubkey&amp;#34;: hex::encode(key_package.verifying_key().serialize()?.as_slice()), // Signer&amp;#39;s public key&lt;br/&gt;        &amp;#34;created_at&amp;#34;: 1712050000, // Example timestamp&lt;br/&gt;        &amp;#34;tags&amp;#34;: [&lt;br/&gt;            [&amp;#34;p&amp;#34;, coordinator_pubkey],       // &amp;#39;p&amp;#39; tag: Directs the event to the coordinator.&lt;br/&gt;            [&amp;#34;i&amp;#34;, session_id],               // &amp;#39;i&amp;#39; tag: Provides a session identifier for filtering/requests.&lt;br/&gt;            [&amp;#34;t&amp;#34;, &amp;#34;frost-signature-share&amp;#34;]   // &amp;#39;t&amp;#39; tag: A searchable label for the event type.&lt;br/&gt;        ],&lt;br/&gt;        &amp;#34;content&amp;#34;: share_hex, // The actual signature share (would be encrypted in production).&lt;br/&gt;        &amp;#34;id&amp;#34;: &amp;#34;...&amp;#34;, // Event ID (filled by relay upon publishing)&lt;br/&gt;        &amp;#34;sig&amp;#34;: &amp;#34;...&amp;#34; // Event signature (filled by relay upon publishing)&lt;br/&gt;    });&lt;br/&gt;&lt;br/&gt;    Ok(event.to_string())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;pub fn simulate_frost_mailbox_post_signer() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    use rand::thread_rng;&lt;br/&gt;    use std::collections::BTreeMap;&lt;br/&gt;    use frost_secp256k1_tr as frost;&lt;br/&gt;&lt;br/&gt;    // This example simulates a single signer&amp;#39;s role in a ROAST mailbox post workflow.&lt;br/&gt;    // The general workflow is:&lt;br/&gt;    // 1. Coordinator sends a request for signatures (e.g., on a BIP-64MOD proposal).&lt;br/&gt;    // 2. Signers receive the proposal, perform local verification.&lt;br/&gt;    // 3. Each signer generates their signature share and posts it (encrypted) to a&lt;br/&gt;    //    Nostr relay, targeting the coordinator&amp;#39;s mailbox.&lt;br/&gt;    // 4. The coordinator collects enough shares to aggregate the final signature.&lt;br/&gt;&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    // For this example, we simulate a 2-of-2 threshold for simplicity.&lt;br/&gt;    let (max_signers, min_signers) = (2, 2);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 1. Key Generation (Simulated Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // In a real distributed setup, this would be DKG. Here, a &amp;#34;trusted dealer&amp;#34;&lt;br/&gt;    // generates the shares and public key package.&lt;br/&gt;    let (shares, _pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // For a 2-of-2 scheme, we have two signers. Let&amp;#39;s pick signer 1.&lt;br/&gt;    let signer1_id = frost::Identifier::try_from(1 as u16)?;&lt;br/&gt;    let key_package1: frost::keys::KeyPackage = shares[&amp;amp;signer1_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    let signer2_id = frost::Identifier::try_from(2 as u16)?;&lt;br/&gt;    let key_package2: frost::keys::KeyPackage = shares[&amp;amp;signer2_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    // The message that is to be signed (e.g., a hash of a Git commit or a Nostr event ID).&lt;br/&gt;    let message = b&amp;#34;This is a test message for ROAST mailbox post.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 2. Round 1: Commitment Phase (Signer&amp;#39;s role)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Each signer generates nonces and commitments.&lt;br/&gt;    let (nonces1, comms1) = frost::round1::commit(key_package1.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    let (nonces2, comms2) = frost::round1::commit(key_package2.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    &lt;br/&gt;    // The coordinator collects these commitments. Here, we simulate by putting them in a BTreeMap.&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    session_commitments.insert(signer1_id, comms1);&lt;br/&gt;    session_commitments.insert(signer2_id, comms2);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 3. Signing Package Creation (Coordinator&amp;#39;s role, simulated for context)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // The coordinator combines the collected commitments and the message to be signed&lt;br/&gt;    // into a signing package, which is then sent back to the signers.&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments, message);&lt;br/&gt;&lt;br/&gt;    // Dummy coordinator public key. In a real scenario, this would be the&lt;br/&gt;    // actual public key of the ROAST coordinator, used for event tagging&lt;br/&gt;    // and encryption (NIP-44).&lt;br/&gt;    let coordinator_pubkey_hex = &amp;#34;0000000000000000000000000000000000000000000000000000000000000001&amp;#34;;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 4. Create the Signer Event (Signer&amp;#39;s role)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // We demonstrate for signer 1. Signer 2 would perform a similar action.&lt;br/&gt;    let event_json_signer1 = create_signer_event(&lt;br/&gt;        signer1_id,&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;nonces1,&lt;br/&gt;        &amp;amp;key_package1,&lt;br/&gt;        coordinator_pubkey_hex,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Generated Nostr Event for Signer 1 Mailbox Post:&lt;br/&gt;{}&amp;#34;, event_json_signer1);&lt;br/&gt;&lt;br/&gt;    // Similarly, Signer 2 would generate their event:&lt;br/&gt;    let event_json_signer2 = create_signer_event(&lt;br/&gt;        signer2_id,&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;nonces2,&lt;br/&gt;        &amp;amp;key_package2,&lt;br/&gt;        coordinator_pubkey_hex,&lt;br/&gt;    )?;&lt;br/&gt;    println!(&amp;#34;Generated Nostr Event for Signer 2 Mailbox Post:&lt;br/&gt;{}&amp;#34;, event_json_signer2);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}
    </content>
    <updated>2026-04-04T01:47:23Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsfwym0zal7xjgfcttf9gxg9gx3alz5es2svlaf3ujxza8h99s0kpgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjksp3kq</id>
    
      <title type="html">#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))] ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsfwym0zal7xjgfcttf9gxg9gx3alz5es2svlaf3ujxza8h99s0kpgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjksp3kq" />
    <content type="html">
      #[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use std::fs;&lt;br/&gt;    use std::path::PathBuf;&lt;br/&gt;&lt;br/&gt;    let manifest_dir = PathBuf::from(std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap());&lt;br/&gt;    let crate_src_path = manifest_dir.join(&amp;#34;src&amp;#34;).join(&amp;#34;online_relays_gps.csv&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Only download if the file doesn&amp;#39;t exist or is empty&lt;br/&gt;    if !crate_src_path.exists() || fs::metadata(&amp;amp;crate_src_path).map(|m| m.len() == 0).unwrap_or(true) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Downloading online_relays_gps.csv...&amp;#34;);&lt;br/&gt;        let url = &amp;#34;&lt;a href=&#34;https://raw.githubusercontent.com/permissionlesstech/bitchat/main/relays/online_relays_gps.csv&amp;#34&#34;&gt;https://raw.githubusercontent.com/permissionlesstech/bitchat/main/relays/online_relays_gps.csv&amp;#34&lt;/a&gt;;;&lt;br/&gt;        match reqwest::get(url).await {&lt;br/&gt;            Ok(response) =&amp;gt; {&lt;br/&gt;                if response.status().is_success() {&lt;br/&gt;                    match response.text().await {&lt;br/&gt;                        Ok(content) =&amp;gt; {&lt;br/&gt;                            fs::write(&amp;amp;crate_src_path, content).expect(&amp;#34;Unable to write online_relays_gps.csv&amp;#34;);&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Successfully downloaded online_relays_gps.csv to {:?}&amp;#34;, crate_src_path);&lt;br/&gt;                        },&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to get text from response: {}&amp;#34;, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                } else {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to download online_relays_gps.csv: HTTP status {}&amp;#34;, response.status());&lt;br/&gt;                }&lt;br/&gt;            },&lt;br/&gt;            Err(e) =&amp;gt; {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to fetch online_relays_gps.csv: {}&amp;#34;, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;)))]&lt;br/&gt;fn main() {&lt;br/&gt;    // Placeholder for when the nostr feature is not enabled or in debug mode&lt;br/&gt;    println!(&amp;#34;cargo:warning=Skipping online_relays_gps.csv download (nostr feature not enabled or debug mode)&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:47:03Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsp6e4hyrp8sk58mk4r90rw62ahh9yp75kv8fthrthc9utn7p3cvgszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjsmsgrl</id>
    
      <title type="html">[package] name = &amp;#34;get_file_hash_core&amp;#34; version = { ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsp6e4hyrp8sk58mk4r90rw62ahh9yp75kv8fthrthc9utn7p3cvgszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjsmsgrl" />
    <content type="html">
      [package]&lt;br/&gt;name = &amp;#34;get_file_hash_core&amp;#34;&lt;br/&gt;version = { workspace = true }&lt;br/&gt;edition = { workspace = true }&lt;br/&gt;description = { workspace = true }&lt;br/&gt;license = { workspace = true }&lt;br/&gt;documentation = { workspace = true }&lt;br/&gt;homepage = { workspace = true }&lt;br/&gt;repository = { workspace = true }&lt;br/&gt;authors = { workspace = true }&lt;br/&gt;&lt;br/&gt;[features]&lt;br/&gt;nostr = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:serde_json&amp;#34;, &amp;#34;dep:sha2&amp;#34;, &amp;#34;dep:hex&amp;#34;, &amp;#34;dep:reqwest&amp;#34;, &amp;#34;dep:tokio&amp;#34;, &amp;#34;dep:csv&amp;#34;, &amp;#34;dep:url&amp;#34;, &amp;#34;dep:frost-secp256k1-tr&amp;#34;, &amp;#34;dep:rand&amp;#34;]&lt;br/&gt;frost = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:serde_json&amp;#34;, &amp;#34;dep:sha2&amp;#34;, &amp;#34;dep:hex&amp;#34;, &amp;#34;dep:reqwest&amp;#34;, &amp;#34;dep:tokio&amp;#34;, &amp;#34;dep:csv&amp;#34;, &amp;#34;dep:url&amp;#34;, &amp;#34;dep:frost-secp256k1-tr&amp;#34;, &amp;#34;dep:rand&amp;#34;]&lt;br/&gt;&lt;br/&gt;[dependencies]&lt;br/&gt;sha2 = { workspace = true, optional = true }&lt;br/&gt;nostr = { workspace = true, optional = true }&lt;br/&gt;serde_json = { workspace = true, optional = true }&lt;br/&gt;nostr-sdk = { workspace = true, optional = true }&lt;br/&gt;hex = { workspace = true, optional = true }&lt;br/&gt;csv = { workspace = true, optional = true }&lt;br/&gt;url = { workspace = true, optional = true }&lt;br/&gt;frost-secp256k1-tr = { workspace = true, optional = true }&lt;br/&gt;rand = { workspace = true, optional = true }&lt;br/&gt;&lt;br/&gt;[dev-dependencies]&lt;br/&gt;sha2 = { workspace = true }&lt;br/&gt;tempfile = { workspace = true }&lt;br/&gt;nostr = { workspace = true }&lt;br/&gt;nostr-sdk = { workspace = true }&lt;br/&gt;serde_json = { workspace = true }&lt;br/&gt;hex = { workspace = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;macros&amp;#34;, &amp;#34;rt-multi-thread&amp;#34;] }&lt;br/&gt;csv = { workspace = true }&lt;br/&gt;url = { workspace = true }&lt;br/&gt;frost-secp256k1-tr = { workspace = true }&lt;br/&gt;serial_test = { workspace = true, features = [&amp;#34;test_logging&amp;#34;] }&lt;br/&gt;log = { workspace = true }&lt;br/&gt;&lt;br/&gt;[build-dependencies]&lt;br/&gt;reqwest = { workspace = true, features = [&amp;#34;json&amp;#34;], optional = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;macros&amp;#34;, &amp;#34;rt-multi-thread&amp;#34;], optional = true }&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:46:48Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsr7992f2cx89x80selyx63pd4kcf5zvvvgjayvs7uns6jk8y56hxgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjpg7f48</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsr7992f2cx89x80selyx63pd4kcf5zvvvgjayvs7uns6jk8y56hxgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjpg7f48" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;use get_file_hash::{BUILD_HASH, CARGO_TOML_HASH, LIB_HASH};&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART0: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use get_file_hash::CARGO_TOML_HASH;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let readme_hash = get_file_hash!(&amp;#34;src/bin/readme.rs&amp;#34;);&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, lib_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/bin/readme.rs is: {}&amp;#34;, readme_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of Cargo.toml is: {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r&amp;#34;## Release&lt;br/&gt;## [`README.md`](./README.md)&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin readme &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## [`src/bin/readme.rs`](src/bin/readme.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/readme.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`build.rs`](build.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `build.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART3: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`Cargo.toml`](Cargo.toml)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `Cargo.toml`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART4: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`src/lib.rs`](src/lib.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/lib.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART_NIP34: &amp;amp;str = r&amp;#34;## NIP-34 Integration: Git Repository Events on Nostr&lt;br/&gt;&lt;br/&gt;This library provides a set of powerful macros and functions for integrating Git repository events with the Nostr protocol, adhering to the [NIP-34: Git Repositories on Nostr](&lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/34.md&#34;&gt;https://github.com/nostr-protocol/nips/blob/master/34.md&lt;/a&gt;) specification.&lt;br/&gt;&lt;br/&gt;These tools allow you to publish various Git-related events to Nostr relays, enabling decentralized tracking and collaboration for your code repositories.&lt;br/&gt;&lt;br/&gt;### Available NIP-34 Macros&lt;br/&gt;&lt;br/&gt;Each macro provides a convenient way to publish specific NIP-34 event kinds:&lt;br/&gt;&lt;br/&gt;*   [`repository_announcement!`](#repository_announcement)&lt;br/&gt;    *   Publishes a `Repository Announcement` event (Kind 30617) to announce a new or updated Git repository.&lt;br/&gt;*   [`publish_patch!`](#publish_patch)&lt;br/&gt;    *   Publishes a `Patch` event (Kind 1617) containing a Git patch (diff) for a specific commit.&lt;br/&gt;*   [`publish_pull_request!`](#publish_pull_request)&lt;br/&gt;    *   Publishes a `Pull Request` event (Kind 1618) to propose changes and facilitate code review.&lt;br/&gt;*   [`publish_pr_update!`](#publish_pr_update)&lt;br/&gt;    *   Publishes a `Pull Request Update` event (Kind 1619) to update an existing pull request.&lt;br/&gt;*   [`publish_repository_state!`](#publish_repository_state)&lt;br/&gt;    *   Publishes a `Repository State` event (Kind 1620) to announce the current state of a branch (e.g., its latest commit).&lt;br/&gt;*   [`publish_issue!`](#publish_issue)&lt;br/&gt;    *   Publishes an `Issue` event (Kind 1621) to report bugs, request features, or track tasks.&lt;br/&gt;&lt;br/&gt;### Running NIP-34 Examples&lt;br/&gt;&lt;br/&gt;To see these macros in action, navigate to the `examples/` directory and run each example individually with the `nostr` feature enabled:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --example repository_announcement --features nostr&lt;br/&gt;cargo run --example publish_patch --features nostr&lt;br/&gt;cargo run --example publish_pull_request --features nostr&lt;br/&gt;cargo run --example publish_pr_update --features nostr&lt;br/&gt;cargo run --example publish_repository_state --features nostr&lt;br/&gt;cargo run --example publish_issue --features nostr&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`readme.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;readme.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    let build_message = if BUILD_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let cargo_message = if CARGO_TOML_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let lib_message = if LIB_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}{}&amp;#34;, README_TEMPLATE_PART0, README_TEMPLATE_PART1, README_TEMPLATE_PART_NIP34);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, BUILD_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, build_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART3);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, cargo_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART4);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, LIB_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, lib_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:46:37Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsz2rkxav0j5z7ce272au5gx0c875ceujwtku8fnraj3cyylg8dmxczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjx29cph</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsz2rkxav0j5z7ce272au5gx0c875ceujwtku8fnraj3cyylg8dmxczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjx29cph" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let file_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, file_hash);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;## Setup and Building&lt;br/&gt;&lt;br/&gt;1.  **Clone the repository:**&lt;br/&gt;    ```bash&lt;br/&gt;    git clone &amp;lt;repository-url&amp;gt;&lt;br/&gt;    cd &amp;lt;repository-name&amp;gt;&lt;br/&gt;    ```&lt;br/&gt;2.  **Build the project:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build&lt;br/&gt;    ```&lt;br/&gt;    During the build, `build.rs` will execute and print the hash of `Cargo.toml`.&lt;br/&gt;3.  **Run the example executable:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo run --bin get_file_hash&lt;br/&gt;    ```&lt;br/&gt;    This will print the hash of `src/bin/get_file_hash.rs` to your console.&lt;br/&gt;&lt;br/&gt;## Updating this `README.md`&lt;br/&gt;&lt;br/&gt;The hash information in this `README.md` is automatically generated by running the example executable.&lt;br/&gt;To update it, execute:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin get_file_hash &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## Current File Hash Information (of `src/bin/get_file_hash.rs`)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/get_file_hash.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`get_file_hash.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}&amp;#34;, README_TEMPLATE_PART1, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:46:26Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsgy0vmlau9vsdyxt4vddm3ekmjd5gft5fdlrumdj2lv22sdgfnp5qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjkpzzrd</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsgy0vmlau9vsdyxt4vddm3ekmjd5gft5fdlrumdj2lv22sdgfnp5qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjkpzzrd" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let max_signers = 3;&lt;br/&gt;    let min_signers = 2;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 0: Key Generation (Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    // In a real P2P setup, you&amp;#39;d use Distributed Key Generation (DKG).&lt;br/&gt;    // For local testing/simulations, the trusted dealer is faster.&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verifying the public key exists&lt;br/&gt;    let group_public_key = pubkey_package.verifying_key();&lt;br/&gt;    println!(&amp;#34;Group Public Key: {:?}&amp;#34;, group_public_key);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 1: Commitment&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let message = b&amp;#34;BIP-64MOD Consensus Proposal&amp;#34;;&lt;br/&gt;    let mut signing_commitments = BTreeMap::new();&lt;br/&gt;    let mut participant_nonces = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    // Participants 1 and 2 decide to sign&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        &lt;br/&gt;        // Generate nonces and commitments&lt;br/&gt;        let (nonces, commitments) = frost::round1::commit(&lt;br/&gt;            shares[&amp;amp;identifier].signing_share(),&lt;br/&gt;            &amp;amp;mut rng,&lt;br/&gt;        );&lt;br/&gt;        &lt;br/&gt;        signing_commitments.insert(identifier, commitments);&lt;br/&gt;        participant_nonces.insert(identifier, nonces);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 2: Signing&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let mut signature_shares = BTreeMap::new();&lt;br/&gt;    let signing_package = frost::SigningPackage::new(signing_commitments, message);&lt;br/&gt;&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        let nonces = &amp;amp;participant_nonces[&amp;amp;identifier];&lt;br/&gt;        &lt;br/&gt;        // Each participant produces a signature share&lt;br/&gt;        let key_package: frost::keys::KeyPackage = shares[&amp;amp;identifier].clone().try_into()?;&lt;br/&gt;        let share = frost::round2::sign(&amp;amp;signing_package, nonces, &amp;amp;key_package)?;&lt;br/&gt;        signature_shares.insert(identifier, share);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Finalization: Aggregation&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let group_signature = frost::aggregate(&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;signature_shares,&lt;br/&gt;        &amp;amp;pubkey_package,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verification&lt;br/&gt;    group_public_key.verify(message, &amp;amp;group_signature)?;&lt;br/&gt;    &lt;br/&gt;    println!(&amp;#34;Threshold signature verified successfully!&amp;#34;);&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example trusted-dealer --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:46:15Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqst3k9mdga5smr846828ngua3kl5x429855gzqzte29wy07dzdmjtczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj7mdjue</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqst3k9mdga5smr846828ngua3kl5x429855gzqzte29wy07dzdmjtczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj7mdjue" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;/// A simplified ROAST Coordinator that manages signing sessions&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;struct RoastCoordinator {&lt;br/&gt;    min_signers: u16,&lt;br/&gt;    _message: Vec&amp;lt;u8&amp;gt;,&lt;br/&gt;    commitments: BTreeMap&amp;lt;frost::Identifier, frost::round1::SigningCommitments&amp;gt;,&lt;br/&gt;    nonces: BTreeMap&amp;lt;frost::Identifier, frost::round1::SigningNonces&amp;gt;,&lt;br/&gt;    shares: BTreeMap&amp;lt;frost::Identifier, frost::round2::SignatureShare&amp;gt;,&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;impl RoastCoordinator {&lt;br/&gt;    fn new(min_signers: u16, message: &amp;amp;[u8]) -&amp;gt; Self {&lt;br/&gt;        Self {&lt;br/&gt;            min_signers,&lt;br/&gt;            _message: message.to_vec(),&lt;br/&gt;            commitments: BTreeMap::new(),&lt;br/&gt;            nonces: BTreeMap::new(),&lt;br/&gt;            shares: BTreeMap::new(),&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// ROAST Logic: Collect commitments until we hit the threshold.&lt;br/&gt;    /// In a real P2P system, this would be an async stream handler.&lt;br/&gt;    fn add_commitment(&amp;amp;mut self, id: frost::Identifier, comms: frost::round1::SigningCommitments, nonces: frost::round1::SigningNonces) {&lt;br/&gt;        if self.commitments.len() &amp;lt; self.min_signers as usize {&lt;br/&gt;            self.commitments.insert(id, comms);&lt;br/&gt;            self.nonces.insert(id, nonces);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// ROAST Logic: Collect signature shares.&lt;br/&gt;    fn add_share(&amp;amp;mut self, id: frost::Identifier, share: frost::round2::SignatureShare) {&lt;br/&gt;        if self.shares.len() &amp;lt; self.min_signers as usize {&lt;br/&gt;            self.shares.insert(id, share);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    fn is_ready_to_sign(&amp;amp;self) -&amp;gt; bool {&lt;br/&gt;        self.commitments.len() &amp;gt;= self.min_signers as usize&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    fn is_ready_to_aggregate(&amp;amp;self) -&amp;gt; bool {&lt;br/&gt;        self.shares.len() &amp;gt;= self.min_signers as usize&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (5, 3);&lt;br/&gt;    let message = b&amp;#34;BIP-64MOD Context: ROAST Coordination&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // 1. Setup: Generate keys (Dealer mode for simulation)&lt;br/&gt;    let (key_shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    let mut coordinator = RoastCoordinator::new(min_signers, message);&lt;br/&gt;&lt;br/&gt;    // 2. Round 1: Asynchronous Commitment Collection&lt;br/&gt;    // Simulate signers 1, 3, and 5 responding first (ROAST skips 2 and 4)&lt;br/&gt;    for &amp;amp;id_num in &amp;amp;[1, 3, 5] {&lt;br/&gt;        let id = frost::Identifier::try_from(id_num as u16)?;&lt;br/&gt;        let (nonces, comms) = frost::round1::commit(key_shares[&amp;amp;id].signing_share(), &amp;amp;mut rng);&lt;br/&gt;        &lt;br/&gt;        // Signers store their nonces locally, send comms to coordinator&lt;br/&gt;        coordinator.add_commitment(id, comms, nonces);&lt;br/&gt;        &lt;br/&gt;        // Note: Signer 2 was &amp;#34;offline&amp;#34;, but ROAST doesn&amp;#39;t care because we hit 3/5.&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 3. Round 2: Signing&lt;br/&gt;    if coordinator.is_ready_to_sign() {&lt;br/&gt;        let signing_package = frost::SigningPackage::new(coordinator.commitments.clone(), message);&lt;br/&gt;        &lt;br/&gt;        let mut temp_shares = BTreeMap::new();&lt;br/&gt;        for &amp;amp;id in coordinator.commitments.keys() {&lt;br/&gt;            // In reality, coordinator sends signing_package to signers&lt;br/&gt;            // Here we simulate the signers producing shares&lt;br/&gt;&lt;br/&gt;            let nonces = &amp;amp;coordinator.nonces[&amp;amp;id];&lt;br/&gt;            &lt;br/&gt;            let key_package: frost::keys::KeyPackage = key_shares[&amp;amp;id].clone().try_into()?;&lt;br/&gt;            let share = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces, &amp;amp;key_package)?;&lt;br/&gt;            temp_shares.insert(id, share);&lt;br/&gt;        }&lt;br/&gt;        for (id, share) in temp_shares {&lt;br/&gt;            coordinator.add_share(id, share);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 4. Finalization: Aggregation&lt;br/&gt;    if coordinator.is_ready_to_aggregate() {&lt;br/&gt;        let signing_package = frost::SigningPackage::new(coordinator.commitments.clone(), message);&lt;br/&gt;        let group_signature = frost::aggregate(&lt;br/&gt;            &amp;amp;signing_package,&lt;br/&gt;            &amp;amp;coordinator.shares,&lt;br/&gt;            &amp;amp;pubkey_package,&lt;br/&gt;        )?;&lt;br/&gt;&lt;br/&gt;        pubkey_package.verifying_key().verify(message, &amp;amp;group_signature)?;&lt;br/&gt;        println!(&amp;#34;ROAST-coordinated signature verified!&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example roast-experiment --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:46:01Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsp53jjdc00y3yeylnlsv4dwaqd6cgs4acpvdhtfy43q5twy9sj5yczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjmppx8y</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsp53jjdc00y3yeylnlsv4dwaqd6cgs4acpvdhtfy43q5twy9sj5yczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjmppx8y" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[allow(unused_imports)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::repository_announcement;&lt;br/&gt;    use get_file_hash_core::get_file_hash;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use sha2::{Digest, Sha256};&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let project_name = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let description = &amp;#34;A fantastic new project example.&amp;#34;;&lt;br/&gt;    let clone_url = &amp;#34;git@github.com:user/my-awesome-repo-example.git&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing repository announcement without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    repository_announcement!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        project_name,&lt;br/&gt;        description,&lt;br/&gt;        clone_url,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use a known file in your project&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository announcement without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing repository announcement with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    repository_announcement!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        project_name,&lt;br/&gt;        description,&lt;br/&gt;        clone_url,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use a known file in your project&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository announcement with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example repository_announcement --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:45:46Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqszdlyhuchr2zg384kdwnq9q5v5uqu0g837q6c5sj4l7uuj7ymxwkczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjppxwxn</id>
    
      <title type="html">Build manifest for get_file_hash v0.3.3</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqszdlyhuchr2zg384kdwnq9q5v5uqu0g837q6c5sj4l7uuj7ymxwkczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjppxwxn" />
    <content type="html">
      In reply to &lt;a href=&#39;/nevent1qqsfxu8fdvlts5z5f8t9pzwx58u7syq3t68ajdy3gwavtkfgzval0sgrsdhl4&#39;&gt;nevent1q…dhl4&lt;/a&gt;&lt;br/&gt;_________________________&lt;br/&gt;&lt;br/&gt;Build manifest for get_file_hash v0.3.3
    </content>
    <updated>2026-04-04T01:45:38Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsyktz5xuhk73rlv683zudjffjtj4vqp3rm4cu4s7ha7x5ptuesncczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj5rjxkx</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsyktz5xuhk73rlv683zudjffjtj4vqp3rm4cu4s7ha7x5ptuesncczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj5rjxkx" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_repository_state;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let branch_name = &amp;#34;main&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Publishing repository state...&amp;#34;);&lt;br/&gt;    publish_repository_state!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        branch_name,&lt;br/&gt;        commit_id&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository state published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_repository_state --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:45:35Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsfxu8fdvlts5z5f8t9pzwx58u7syq3t68ajdy3gwavtkfgzval0sgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj6aar4e</id>
    
      <title type="html">&amp;lt;?xml version=&amp;#39;1.0&amp;#39; ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsfxu8fdvlts5z5f8t9pzwx58u7syq3t68ajdy3gwavtkfgzval0sgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj6aar4e" />
    <content type="html">
      &amp;lt;?xml version=&amp;#39;1.0&amp;#39; encoding=&amp;#39;windows-1252&amp;#39;?&amp;gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  Copyright (C) 2017 Christopher R. Field.&lt;br/&gt;&lt;br/&gt;  Licensed under the Apache License, Version 2.0 (the &amp;#34;License&amp;#34;);&lt;br/&gt;  you may not use this file except in compliance with the License.&lt;br/&gt;  You may obtain a copy of the License at&lt;br/&gt;&lt;br/&gt;  &lt;a href=&#34;http://www.apache.org/licenses/LICENSE-2.0&#34;&gt;http://www.apache.org/licenses/LICENSE-2.0&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;  Unless required by applicable law or agreed to in writing, software&lt;br/&gt;  distributed under the License is distributed on an &amp;#34;AS IS&amp;#34; BASIS,&lt;br/&gt;  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;br/&gt;  See the License for the specific language governing permissions and&lt;br/&gt;  limitations under the License.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  The &amp;#34;cargo wix&amp;#34; subcommand provides a variety of predefined variables available&lt;br/&gt;  for customization of this template. The values for each variable are set at&lt;br/&gt;  installer creation time. The following variables are available:&lt;br/&gt;&lt;br/&gt;  TargetTriple      = The rustc target triple name.&lt;br/&gt;  TargetEnv         = The rustc target environment. This is typically either&lt;br/&gt;                      &amp;#34;msvc&amp;#34; or &amp;#34;gnu&amp;#34; depending on the toolchain downloaded and&lt;br/&gt;                      installed.&lt;br/&gt;  TargetVendor      = The rustc target vendor. This is typically &amp;#34;pc&amp;#34;, but Rust&lt;br/&gt;                      does support other vendors, like &amp;#34;uwp&amp;#34;.&lt;br/&gt;  CargoTargetBinDir = The complete path to the directory containing the&lt;br/&gt;                      binaries (exes) to include. The default would be&lt;br/&gt;                      &amp;#34;target\release\&amp;#34;. If an explicit rustc target triple is&lt;br/&gt;                      used, i.e. cross-compiling, then the default path would&lt;br/&gt;                      be &amp;#34;target\&amp;lt;CARGO_TARGET&amp;gt;\&amp;lt;CARGO_PROFILE&amp;gt;&amp;#34;,&lt;br/&gt;                      where &amp;#34;&amp;lt;CARGO_TARGET&amp;gt;&amp;#34; is replaced with the &amp;#34;CargoTarget&amp;#34;&lt;br/&gt;                      variable value and &amp;#34;&amp;lt;CARGO_PROFILE&amp;gt;&amp;#34; is replaced with the&lt;br/&gt;                      value from the &amp;#34;CargoProfile&amp;#34; variable. This can also&lt;br/&gt;                      be overridden manually with the &amp;#34;target-bin-dir&amp;#34; flag.&lt;br/&gt;  CargoTargetDir    = The path to the directory for the build artifacts, i.e.&lt;br/&gt;                      &amp;#34;target&amp;#34;.&lt;br/&gt;  CargoProfile      = The cargo profile used to build the binaries&lt;br/&gt;                      (usually &amp;#34;debug&amp;#34; or &amp;#34;release&amp;#34;).&lt;br/&gt;  Version           = The version for the installer. The default is the&lt;br/&gt;                      &amp;#34;Major.Minor.Fix&amp;#34; semantic versioning number of the Rust&lt;br/&gt;                      package.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  Please do not remove these pre-processor If-Else blocks. These are used with&lt;br/&gt;  the `cargo wix` subcommand to automatically determine the installation&lt;br/&gt;  destination for 32-bit versus 64-bit installers. Removal of these lines will&lt;br/&gt;  cause installation errors.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&amp;lt;?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64 ?&amp;gt;&lt;br/&gt;    &amp;lt;?define PlatformProgramFilesFolder = &amp;#34;ProgramFiles64Folder&amp;#34; ?&amp;gt;&lt;br/&gt;&amp;lt;?else ?&amp;gt;&lt;br/&gt;    &amp;lt;?define PlatformProgramFilesFolder = &amp;#34;ProgramFilesFolder&amp;#34; ?&amp;gt;&lt;br/&gt;&amp;lt;?endif ?&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;Wix xmlns=&amp;#39;&lt;a href=&#34;http://schemas.microsoft.com/wix/2006/wi&amp;#39;&amp;gt&#34;&gt;http://schemas.microsoft.com/wix/2006/wi&amp;#39;&amp;gt&lt;/a&gt;;&lt;br/&gt;&lt;br/&gt;    &amp;lt;Product&lt;br/&gt;        Id=&amp;#39;*&amp;#39;&lt;br/&gt;        Name=&amp;#39;get_file_hash&amp;#39;&lt;br/&gt;        UpgradeCode=&amp;#39;DED69220-26E3-4406-B564-7F2B58C56F57&amp;#39;&lt;br/&gt;        Manufacturer=&amp;#39;gnostr admin@gnostr.org&amp;#39;&lt;br/&gt;        Language=&amp;#39;1033&amp;#39;&lt;br/&gt;        Codepage=&amp;#39;1252&amp;#39;&lt;br/&gt;        Version=&amp;#39;$(var.Version)&amp;#39;&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Package Id=&amp;#39;*&amp;#39;&lt;br/&gt;            Keywords=&amp;#39;Installer&amp;#39;&lt;br/&gt;            Description=&amp;#39;A utility crate providing a procedural macro to compute and embed file hashes at compile time.&amp;#39;&lt;br/&gt;            Manufacturer=&amp;#39;gnostr admin@gnostr.org&amp;#39;&lt;br/&gt;            InstallerVersion=&amp;#39;450&amp;#39;&lt;br/&gt;            Languages=&amp;#39;1033&amp;#39;&lt;br/&gt;            Compressed=&amp;#39;yes&amp;#39;&lt;br/&gt;            InstallScope=&amp;#39;perMachine&amp;#39;&lt;br/&gt;            SummaryCodepage=&amp;#39;1252&amp;#39;&lt;br/&gt;            /&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;MajorUpgrade&lt;br/&gt;            Schedule=&amp;#39;afterInstallInitialize&amp;#39;&lt;br/&gt;            DowngradeErrorMessage=&amp;#39;A newer version of [ProductName] is already installed. Setup will now exit.&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Media Id=&amp;#39;1&amp;#39; Cabinet=&amp;#39;media1.cab&amp;#39; EmbedCab=&amp;#39;yes&amp;#39; DiskPrompt=&amp;#39;CD-ROM #1&amp;#39;/&amp;gt;&lt;br/&gt;        &amp;lt;Property Id=&amp;#39;DiskPrompt&amp;#39; Value=&amp;#39;get_file_hash Installation&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Directory Id=&amp;#39;TARGETDIR&amp;#39; Name=&amp;#39;SourceDir&amp;#39;&amp;gt;&lt;br/&gt;            &amp;lt;Directory Id=&amp;#39;$(var.PlatformProgramFilesFolder)&amp;#39; Name=&amp;#39;PFiles&amp;#39;&amp;gt;&lt;br/&gt;                &amp;lt;Directory Id=&amp;#39;APPLICATIONFOLDER&amp;#39; Name=&amp;#39;get_file_hash&amp;#39;&amp;gt;&lt;br/&gt;                    &lt;br/&gt;                    &amp;lt;!--&lt;br/&gt;                      Enabling the license sidecar file in the installer is a four step process:&lt;br/&gt;&lt;br/&gt;                      1. Uncomment the `Component` tag and its contents.&lt;br/&gt;                      2. Change the value for the `Source` attribute in the `File` tag to a path&lt;br/&gt;                         to the file that should be included as the license sidecar file. The path&lt;br/&gt;                         can, and probably should be, relative to this file.&lt;br/&gt;                      3. Change the value for the `Name` attribute in the `File` tag to the&lt;br/&gt;                         desired name for the file when it is installed alongside the `bin` folder&lt;br/&gt;                         in the installation directory. This can be omitted if the desired name is&lt;br/&gt;                         the same as the file name.&lt;br/&gt;                      4. Uncomment the `ComponentRef` tag with the Id attribute value of &amp;#34;License&amp;#34;&lt;br/&gt;                         further down in this file.&lt;br/&gt;                    --&amp;gt;&lt;br/&gt;                    &amp;lt;!--&lt;br/&gt;                    &amp;lt;Component Id=&amp;#39;License&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                        &amp;lt;File Id=&amp;#39;LicenseFile&amp;#39; Name=&amp;#39;ChangeMe&amp;#39; DiskId=&amp;#39;1&amp;#39; Source=&amp;#39;C:\Path\To\File&amp;#39; KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                    &amp;lt;/Component&amp;gt;&lt;br/&gt;                    --&amp;gt;&lt;br/&gt;&lt;br/&gt;                    &amp;lt;Directory Id=&amp;#39;Bin&amp;#39; Name=&amp;#39;bin&amp;#39;&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;Path&amp;#39; Guid=&amp;#39;8DB39A25-8B99-4C25-8CF5-4704353C7C6E&amp;#39; KeyPath=&amp;#39;yes&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;Environment&lt;br/&gt;                                Id=&amp;#39;PATH&amp;#39;&lt;br/&gt;                                Name=&amp;#39;PATH&amp;#39;&lt;br/&gt;                                Value=&amp;#39;[Bin]&amp;#39;&lt;br/&gt;                                Permanent=&amp;#39;no&amp;#39;&lt;br/&gt;                                Part=&amp;#39;last&amp;#39;&lt;br/&gt;                                Action=&amp;#39;set&amp;#39;&lt;br/&gt;                                System=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;binary0&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;File&lt;br/&gt;                                Id=&amp;#39;exe0&amp;#39;&lt;br/&gt;                                Name=&amp;#39;get_file_hash.exe&amp;#39;&lt;br/&gt;                                DiskId=&amp;#39;1&amp;#39;&lt;br/&gt;                                Source=&amp;#39;$(var.CargoTargetBinDir)\get_file_hash.exe&amp;#39;&lt;br/&gt;                                KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;binary1&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;File&lt;br/&gt;                                Id=&amp;#39;exe1&amp;#39;&lt;br/&gt;                                Name=&amp;#39;readme.exe&amp;#39;&lt;br/&gt;                                DiskId=&amp;#39;1&amp;#39;&lt;br/&gt;                                Source=&amp;#39;$(var.CargoTargetBinDir)\readme.exe&amp;#39;&lt;br/&gt;                                KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                    &amp;lt;/Directory&amp;gt;&lt;br/&gt;                &amp;lt;/Directory&amp;gt;&lt;br/&gt;            &amp;lt;/Directory&amp;gt;&lt;br/&gt;        &amp;lt;/Directory&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Feature&lt;br/&gt;            Id=&amp;#39;Binaries&amp;#39;&lt;br/&gt;            Title=&amp;#39;Application&amp;#39;&lt;br/&gt;            Description=&amp;#39;Installs all binaries and the license.&amp;#39;&lt;br/&gt;            Level=&amp;#39;1&amp;#39;&lt;br/&gt;            ConfigurableDirectory=&amp;#39;APPLICATIONFOLDER&amp;#39;&lt;br/&gt;            AllowAdvertise=&amp;#39;no&amp;#39;&lt;br/&gt;            Display=&amp;#39;expand&amp;#39;&lt;br/&gt;            Absent=&amp;#39;disallow&amp;#39;&amp;gt;&lt;br/&gt;            &lt;br/&gt;            &amp;lt;!--&lt;br/&gt;              Uncomment the following `ComponentRef` tag to add the license&lt;br/&gt;              sidecar file to the installer.&lt;br/&gt;            --&amp;gt;&lt;br/&gt;            &amp;lt;!--&amp;lt;ComponentRef Id=&amp;#39;License&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;            &amp;lt;ComponentRef Id=&amp;#39;binary0&amp;#39;/&amp;gt;&lt;br/&gt;            &amp;lt;ComponentRef Id=&amp;#39;binary1&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;            &amp;lt;Feature&lt;br/&gt;                Id=&amp;#39;Environment&amp;#39;&lt;br/&gt;                Title=&amp;#39;PATH Environment Variable&amp;#39;&lt;br/&gt;                Description=&amp;#39;Add the install location of the [ProductName] executable to the PATH system environment variable. This allows the [ProductName] executable to be called from any location.&amp;#39;&lt;br/&gt;                Level=&amp;#39;1&amp;#39;&lt;br/&gt;                Absent=&amp;#39;allow&amp;#39;&amp;gt;&lt;br/&gt;                &amp;lt;ComponentRef Id=&amp;#39;Path&amp;#39;/&amp;gt;&lt;br/&gt;            &amp;lt;/Feature&amp;gt;&lt;br/&gt;        &amp;lt;/Feature&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;SetProperty Id=&amp;#39;ARPINSTALLLOCATION&amp;#39; Value=&amp;#39;[APPLICATIONFOLDER]&amp;#39; After=&amp;#39;CostFinalize&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the following `Icon` and `Property` tags to change the product icon.&lt;br/&gt;&lt;br/&gt;          The product icon is the graphic that appears in the Add/Remove&lt;br/&gt;          Programs control panel for the application.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;Icon Id=&amp;#39;ProductICO&amp;#39; SourceFile=&amp;#39;wix\Product.ico&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;Property Id=&amp;#39;ARPPRODUCTICON&amp;#39; Value=&amp;#39;ProductICO&amp;#39; /&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Property Id=&amp;#39;ARPHELPLINK&amp;#39; Value=&amp;#39;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash&amp;#39;/&amp;gt&#34;&gt;https://github.com/gnostr-org/get_file_hash&amp;#39;/&amp;gt&lt;/a&gt;;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;UI&amp;gt;&lt;br/&gt;            &amp;lt;UIRef Id=&amp;#39;WixUI_FeatureTree&amp;#39;/&amp;gt;&lt;br/&gt;            &lt;br/&gt;            &amp;lt;!--&lt;br/&gt;              Enabling the EULA dialog in the installer is a three step process:&lt;br/&gt;&lt;br/&gt;                1. Comment out or remove the two `Publish` tags that follow the&lt;br/&gt;                   `WixVariable` tag.&lt;br/&gt;                2. Uncomment the `&amp;lt;WixVariable Id=&amp;#39;WixUILicenseRtf&amp;#39; Value=&amp;#39;Path\to\Eula.rft&amp;#39;&amp;gt;` tag further down&lt;br/&gt;                3. Replace the `Value` attribute of the `WixVariable` tag with&lt;br/&gt;                   the path to a RTF file that will be used as the EULA and&lt;br/&gt;                   displayed in the license agreement dialog.&lt;br/&gt;            --&amp;gt;&lt;br/&gt;            &amp;lt;Publish Dialog=&amp;#39;WelcomeDlg&amp;#39; Control=&amp;#39;Next&amp;#39; Event=&amp;#39;NewDialog&amp;#39; Value=&amp;#39;CustomizeDlg&amp;#39; Order=&amp;#39;99&amp;#39;&amp;gt;1&amp;lt;/Publish&amp;gt;&lt;br/&gt;            &amp;lt;Publish Dialog=&amp;#39;CustomizeDlg&amp;#39; Control=&amp;#39;Back&amp;#39; Event=&amp;#39;NewDialog&amp;#39; Value=&amp;#39;WelcomeDlg&amp;#39; Order=&amp;#39;99&amp;#39;&amp;gt;1&amp;lt;/Publish&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;/UI&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Enabling the EULA dialog in the installer requires uncommenting&lt;br/&gt;          the following `WixUILicenseRTF` tag and changing the `Value`&lt;br/&gt;          attribute.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!-- &amp;lt;WixVariable Id=&amp;#39;WixUILicenseRtf&amp;#39; Value=&amp;#39;Relative\Path\to\Eula.rtf&amp;#39;/&amp;gt; --&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the next `WixVariable` tag to customize the installer&amp;#39;s&lt;br/&gt;          Graphical User Interface (GUI) and add a custom banner image across&lt;br/&gt;          the top of each screen. See the WiX Toolset documentation for details&lt;br/&gt;          about customization.&lt;br/&gt;&lt;br/&gt;          The banner BMP dimensions are 493 x 58 pixels.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;WixVariable Id=&amp;#39;WixUIBannerBmp&amp;#39; Value=&amp;#39;wix\Banner.bmp&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the next `WixVariable` tag to customize the installer&amp;#39;s&lt;br/&gt;          Graphical User Interface (GUI) and add a custom image to the first&lt;br/&gt;          dialog, or screen. See the WiX Toolset documentation for details about&lt;br/&gt;          customization.&lt;br/&gt;&lt;br/&gt;          The dialog BMP dimensions are 493 x 312 pixels.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;WixVariable Id=&amp;#39;WixUIDialogBmp&amp;#39; Value=&amp;#39;wix\Dialog.bmp&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;    &amp;lt;/Product&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;/Wix&amp;gt;&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:45:26Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs9rdjd2f3dpkyegz85v7w7vvy46cwpf4d848p3c2umd9nrkh82xtszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjmpqwfm</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs9rdjd2f3dpkyegz85v7w7vvy46cwpf4d848p3c2umd9nrkh82xtszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjmpqwfm" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_pull_request;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;0123456789abcdef0123456789abcdef01234567&amp;#34;;&lt;br/&gt;    let clone_url = &amp;#34;git@github.com:user/my-feature-branch.git&amp;#34;;&lt;br/&gt;    let title = Some(&amp;#34;Feat: Add new awesome feature example&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without title and build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request without title and build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request without title and build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With title but without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request with title but without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        title&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with title but without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 3: With build_manifest_event_id but without title&lt;br/&gt;    println!(&amp;#34;Publishing pull request with build_manifest_event_id but without title...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        None, // Explicitly pass None for title&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with build_manifest_event_id but without title published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 4: With title and build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request with title and build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        title,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with title and build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_pull_request --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:45:22Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsqwh77hlyellh8l0qjj63sx2dwegvfxmd40nr5nv883ntstqs43kczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjkctmk6</id>
    
      <title type="html">use std::process::Command; use std::fs; use sha2::{Digest, ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsqwh77hlyellh8l0qjj63sx2dwegvfxmd40nr5nv883ntstqs43kczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjkctmk6" />
    <content type="html">
      use std::process::Command;&lt;br/&gt;use std::fs;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn calculate_sha256(file_path: &amp;amp;str) -&amp;gt; String {&lt;br/&gt;    let content = fs::read(file_path).expect(&amp;#34;Unable to read file&amp;#34;);&lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(&amp;amp;content);&lt;br/&gt;    hasher.finalize()&lt;br/&gt;        .iter()&lt;br/&gt;        .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;        .collect()&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[test]&lt;br/&gt;fn test_get_file_hash_binary_no_features() {&lt;br/&gt;    let output = Command::new(&amp;#34;cargo&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;run&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--bin&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;get_file_hash&amp;#34;)&lt;br/&gt;        .output()&lt;br/&gt;        .expect(&amp;#34;Failed to execute command&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let stdout = String::from_utf8_lossy(&amp;amp;output.stdout);&lt;br/&gt;    let stderr = String::from_utf8_lossy(&amp;amp;output.stderr);&lt;br/&gt;&lt;br/&gt;    // Assert that the command ran successfully&lt;br/&gt;    assert!(output.status.success(), &amp;#34;Command failed with stderr: {}&amp;#34;, stderr);&lt;br/&gt;&lt;br/&gt;    // Manually calculate the hash of the binary&amp;#39;s source file&lt;br/&gt;    let expected_hash = calculate_sha256(&amp;#34;src/bin/get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains the correct hash&lt;br/&gt;    // Check for the raw hash first&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash), &amp;#34;Output did not contain raw expected hash. Expected: {}, Actual: {}&amp;#34;, expected_hash, stdout);&lt;br/&gt;&lt;br/&gt;    // Then check for the formatted string, including backticks&lt;br/&gt;    // Use a regex-like check for more flexibility with newlines if needed, or refine to exact match&lt;br/&gt;    let expected_hash_line = format!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, expected_hash);&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash_line), &amp;#34;Output did not contain expected hash line. Expected line: {}, Actual: {}&amp;#34;, expected_hash_line, stdout);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    assert!(stdout.contains(&amp;#34;Integrity Verified.&amp;#34;), &amp;#34;Output did not contain &amp;#39;Integrity Verified.&amp;#39;. stdout: {}&amp;#34;, stdout);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Output from get_file_hash binary (no features):&lt;br/&gt;{}&amp;#34;, stdout);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[test]&lt;br/&gt;fn test_get_file_hash_binary_with_nostr_feature() {&lt;br/&gt;    let output = Command::new(&amp;#34;cargo&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;run&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--bin&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;get_file_hash&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--features&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;nostr&amp;#34;)&lt;br/&gt;        .output()&lt;br/&gt;        .expect(&amp;#34;Failed to execute command&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let stdout = String::from_utf8_lossy(&amp;amp;output.stdout);&lt;br/&gt;    let stderr = String::from_utf8_lossy(&amp;amp;output.stderr);&lt;br/&gt;&lt;br/&gt;    // Assert that the command ran successfully&lt;br/&gt;    assert!(output.status.success(), &amp;#34;Command failed with stderr: {}&amp;#34;, stderr);&lt;br/&gt;&lt;br/&gt;    // Manually calculate the hash of the binary&amp;#39;s source file&lt;br/&gt;    let expected_hash = calculate_sha256(&amp;#34;src/bin/get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains the correct hash&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash), &amp;#34;Output did not contain raw expected hash. Expected: {}, Actual: {}&amp;#34;, expected_hash, stdout);&lt;br/&gt;&lt;br/&gt;    // Then check for the formatted string, including backticks&lt;br/&gt;    let expected_hash_line = format!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, expected_hash);&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash_line), &amp;#34;Output did not contain expected hash line. Expected line: {}, Actual: {}&amp;#34;, expected_hash_line, stdout);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    assert!(stdout.contains(&amp;#34;Integrity Verified.&amp;#34;), &amp;#34;Output did not contain &amp;#39;Integrity Verified.&amp;#39;. stdout: {}&amp;#34;, stdout);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Output from get_file_hash binary (with nostr feature):&lt;br/&gt;{}&amp;#34;, stdout);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:45:15Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsxeqragxpes9jquckagyq9fh8s2qyppkr02lw23fhgv63k23tx7eszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjlzc7ua</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsxeqragxpes9jquckagyq9fh8s2qyppkr02lw23fhgv63k23tx7eszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjlzc7ua" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_pr_update;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let pr_event_id = EventId::from_str(&amp;#34;f6e4d6a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9&amp;#34;).unwrap(); // Example PR Event ID&lt;br/&gt;    let updated_commit_id = &amp;#34;z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0&amp;#34;;&lt;br/&gt;    let updated_clone_url = &amp;#34;git@github.com:user/my-feature-branch-v2.git&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_pr_update --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:45:07Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsyvw8903kvlvgvclgw0ptgfa8my3vfexj4h8u8sk6r0sdqtflfktqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjs3k9er</id>
    
      <title type="html">//! A crate providing the `get_file_hash!` procedural macro. //! ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsyvw8903kvlvgvclgw0ptgfa8my3vfexj4h8u8sk6r0sdqtflfktqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjs3k9er" />
    <content type="html">
      //! A crate providing the `get_file_hash!` procedural macro.&lt;br/&gt;//!&lt;br/&gt;//! This macro allows you to compute the SHA-256 hash of a file at compile time,&lt;br/&gt;//! embedding the resulting hash string directly into your Rust executable.&lt;br/&gt;&lt;br/&gt;pub use get_file_hash_core::get_file_hash;&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `build.rs` at the time of compilation.&lt;br/&gt;pub const BUILD_HASH: &amp;amp;str = env!(&amp;#34;BUILD_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `Cargo.toml` at the time of compilation.&lt;br/&gt;pub const CARGO_TOML_HASH: &amp;amp;str = env!(&amp;#34;CARGO_TOML_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `src/lib.rs` at the time of compilation.&lt;br/&gt;pub const LIB_HASH: &amp;amp;str = env!(&amp;#34;LIB_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The name of the package as specified in Cargo.toml.&lt;br/&gt;pub const CARGO_PKG_NAME: &amp;amp;str = env!(&amp;#34;CARGO_PKG_NAME&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The version of the package as specified in Cargo.toml.&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;/// The git commit hash of the repository at the time of compilation.&lt;br/&gt;pub const GIT_COMMIT_HASH: &amp;amp;str = env!(&amp;#34;GIT_COMMIT_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;/// The git branch of the repository at the time of compilation.&lt;br/&gt;pub const GIT_BRANCH: &amp;amp;str = env!(&amp;#34;GIT_BRANCH&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(test)]&lt;br/&gt;mod tests {&lt;br/&gt;    use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;    use super::*;&lt;br/&gt;&lt;br/&gt;    /// Verifies that the exported CARGO_TOML_HASH is not empty.&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_injected_hash_exists() {&lt;br/&gt;        assert!(!BUILD_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified build.rs Hash:&lt;br/&gt;{}&amp;#34;, BUILD_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_TOML_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Cargo.toml Hash:&lt;br/&gt;{}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!LIB_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified src/lib.rs Hash:\n{}&amp;#34;, LIB_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_PKG_NAME.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Package Name:\n{}&amp;#34;, CARGO_PKG_NAME);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_PKG_VERSION.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Package Version:\n{}&amp;#34;, CARGO_PKG_VERSION);&lt;br/&gt;&lt;br/&gt;        #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;        {&lt;br/&gt;            assert!(!GIT_COMMIT_HASH.is_empty());&lt;br/&gt;            println!(&amp;#34;Verified Git Commit Hash:\n{}&amp;#34;, GIT_COMMIT_HASH);&lt;br/&gt;&lt;br/&gt;            assert!(!GIT_BRANCH.is_empty());&lt;br/&gt;            println!(&amp;#34;Verified Git Branch:\n{}&amp;#34;, GIT_BRANCH);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// Tests that the `get_file_hash!` macro correctly computes the SHA-256&lt;br/&gt;    /// hash of `lib.rs` and that it matches a manually computed hash of the&lt;br/&gt;    /// same file.&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_get_lib_hash() {&lt;br/&gt;        let file_content = include_bytes!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let mut hasher = Sha256::new();&lt;br/&gt;        hasher.update(file_content);&lt;br/&gt;        let expected_hash = hasher&lt;br/&gt;            .finalize()&lt;br/&gt;            .iter()&lt;br/&gt;            .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;            .collect::&amp;lt;String&amp;gt;();&lt;br/&gt;&lt;br/&gt;        let actual_hash = get_file_hash!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;        assert_eq!(actual_hash, expected_hash);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:44:59Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqswskn2jklp2ttd7f4rdzp92fug7cqj8354ul9rere53z2t7dty5dqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjwsgvc0</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqswskn2jklp2ttd7f4rdzp92fug7cqj8354ul9rere53z2t7dty5dqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjwsgvc0" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use get_file_hash_core::{get_relay_urls, publish_patch, publish_metadata_event, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-gnostr-repository-patch-with-metadata-example&amp;#34;; // Repository identifier&lt;br/&gt;    let commit_id = &amp;#34;f1e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6b7a8f9e0&amp;#34;; // Example commit ID&lt;br/&gt;&lt;br/&gt;    // Metadata for NIP-01 event&lt;br/&gt;    let picture_url = DEFAULT_PICTURE_URL;&lt;br/&gt;    let banner_url = DEFAULT_BANNER_URL;&lt;br/&gt;    let metadata_file_path = &amp;#34;./README.md&amp;#34;; // Using README.md content for metadata&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Publishing NIP-01 Metadata Event...&amp;#34;);&lt;br/&gt;    publish_metadata_event(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        picture_url,&lt;br/&gt;        banner_url,&lt;br/&gt;        metadata_file_path&lt;br/&gt;    ).await;&lt;br/&gt;    println!(&amp;#34;NIP-01 Metadata Event published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;&lt;br/&gt;Publishing NIP-34 Patch Event without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use an existing file for the patch content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;NIP-34 Patch Event without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;&lt;br/&gt;Publishing NIP-34 Patch Event with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;NIP-34 Patch Event with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_patch_with_metadata --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:44:56Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsyuqxr2ggh4ax64ddfyr3czt3lncvyjhdqfujz5y0ln29xwg03w6qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj88d48d</id>
    
      <title type="html">Relay URL,Latitude,Longitude wot.nostr.party,36.1627,-86.7816 ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsyuqxr2ggh4ax64ddfyr3czt3lncvyjhdqfujz5y0ln29xwg03w6qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj88d48d" />
    <content type="html">
      Relay URL,Latitude,Longitude&lt;br/&gt;wot.nostr.party,36.1627,-86.7816&lt;br/&gt;nostr.simplex.icu,50.1109,8.68213&lt;br/&gt;relay.snort.social,53.3498,-6.26031&lt;br/&gt;nostr.stakey.net,52.3676,4.90414&lt;br/&gt;relay.mccormick.cx,52.3563,4.95714&lt;br/&gt;nostr.overmind.lol,43.6532,-79.3832&lt;br/&gt;nostriches.club,43.6532,-79.3832&lt;br/&gt;kanagrovv-pyramid.kozow.com,43.4305,-83.9638&lt;br/&gt;relay.toastr.net,40.8054,-74.0241&lt;br/&gt;relay.primal.net,43.6532,-79.3832&lt;br/&gt;r.bitcoinhold.net,43.6532,-79.3832&lt;br/&gt;wot.dtonon.com,43.6532,-79.3832&lt;br/&gt;santo.iguanatech.net,40.8302,-74.1299&lt;br/&gt;relay2.ngengine.org,43.6532,-79.3832&lt;br/&gt;nostr.oxtr.dev,50.4754,12.3683&lt;br/&gt;simplex.icu,50.1109,8.68213&lt;br/&gt;bitchat.nostr1.com,38.6327,-90.1961&lt;br/&gt;relay.nostu.be,40.4167,-3.70329&lt;br/&gt;nostr.mifen.me,43.6532,-79.3832&lt;br/&gt;relay.vantis.ninja,43.6532,-79.3832&lt;br/&gt;nostr-kyomu-haskell.onrender.com,37.7775,-122.397&lt;br/&gt;nostr-relay.amethyst.name,39.0067,-77.4291&lt;br/&gt;relay.bitcoindistrict.org,43.6532,-79.3832&lt;br/&gt;nos.xmark.cc,50.6924,3.20113&lt;br/&gt;relay01.lnfi.network,35.6764,139.65&lt;br/&gt;nostr-dev.wellorder.net,45.5201,-122.99&lt;br/&gt;nostr.rblb.it,43.7094,10.6582&lt;br/&gt;offchain.pub,39.1585,-94.5728&lt;br/&gt;wot.nostr.place,32.7767,-96.797&lt;br/&gt;fanfares.nostr1.com,38.6327,-90.1961&lt;br/&gt;ephemeral.snowflare.cc,43.6532,-79.3832&lt;br/&gt;relay.visionfusen.org,43.6532,-79.3832&lt;br/&gt;nostr.carroarmato0.be,51.0368,3.21186&lt;br/&gt;social.amanah.eblessing.co,48.1046,11.6002&lt;br/&gt;relay.cyphernomad.com,60.4032,25.0321&lt;br/&gt;nostr-rs-relay-qj1h.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ngengine.org,43.6532,-79.3832&lt;br/&gt;relay.nosto.re,51.1792,5.89444&lt;br/&gt;rusty-uat.siberian-albacore.ts.net:8443,35.6764,139.65&lt;br/&gt;nostr.luisschwab.net,43.6532,-79.3832&lt;br/&gt;nostr.aruku.ovh,1.27994,103.849&lt;br/&gt;srtrelay.c-stellar.net,43.6532,-79.3832&lt;br/&gt;nostr.tagomago.me,3.139,101.687&lt;br/&gt;relay.threenine.services,51.5222,-0.62916&lt;br/&gt;nostr.robosats.org,64.1476,-21.9392&lt;br/&gt;nostr.2b9t.xyz,34.0549,-118.243&lt;br/&gt;strfry.apps3.slidestr.net,40.4167,-3.70329&lt;br/&gt;kitchen.zap.cooking,43.6532,-79.3832&lt;br/&gt;relay.homeinhk.xyz,45.5152,-122.678&lt;br/&gt;relay.seq1.net,43.6532,-79.3832&lt;br/&gt;relay.bornheimer.app,50.1109,8.68213&lt;br/&gt;relay.vrtmrz.net,43.6532,-79.3832&lt;br/&gt;nostr.red5d.dev,43.6532,-79.3832&lt;br/&gt;relay-freeharmonypeople.space,38.7223,-9.13934&lt;br/&gt;aaa-api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;dev.relay.edufeed.org,49.4521,11.0767&lt;br/&gt;nostr.myshosholoza.co.za,52.3913,4.66545&lt;br/&gt;nostr.plantroon.com,50.1013,8.62643&lt;br/&gt;wot.dergigi.com,64.1476,-21.9392&lt;br/&gt;npub1spxdug4m3y24hpx5crm0el4zhkk0wafs8kp6m0xu0wecygqej2xqq8gyhx.fips.network,43.6532,-79.3832&lt;br/&gt;nostrelay.circum.space,52.3676,4.90414&lt;br/&gt;relay.dreamith.to,43.6532,-79.3832&lt;br/&gt;relay.nostriches.club,43.6532,-79.3832&lt;br/&gt;nostr-relayrs.gateway.in.th,15.5163,103.194&lt;br/&gt;nostr.chrissexton.org,43.6532,-79.3832&lt;br/&gt;relay.flashapp.me,43.652,-79.3633&lt;br/&gt;nostr-relay-1.trustlessenterprise.com,43.6532,-79.3832&lt;br/&gt;strfry.shock.network,39.0438,-77.4874&lt;br/&gt;relay.snotr.nl:49999,52.0195,4.42946&lt;br/&gt;spatia-arcana.com,34.0362,-118.443&lt;br/&gt;nostr.computingcache.com,34.0356,-118.442&lt;br/&gt;nostr.self-determined.de,53.5,10.25&lt;br/&gt;relay.sharegap.net,43.6532,-79.3832&lt;br/&gt;spookstr2.nostr1.com,38.6327,-90.1961&lt;br/&gt;v-relay.d02.vrtmrz.net,34.6937,135.502&lt;br/&gt;bridge.tagomago.me,3.139,101.687&lt;br/&gt;antiprimal.net,43.6532,-79.3832&lt;br/&gt;relay.nostrdice.com,-33.8688,151.209&lt;br/&gt;purpura.cloud,43.6532,-79.3832&lt;br/&gt;espelho.girino.org,43.6532,-79.3832&lt;br/&gt;relay.mostro.network,40.8302,-74.1299&lt;br/&gt;temp.iris.to,43.6532,-79.3832&lt;br/&gt;pyramid.self-determined.de,53.5,10.25&lt;br/&gt;relay.jeffg.fyi,43.6532,-79.3832&lt;br/&gt;nostr.aruku.kro.kr,37.3589,127.115&lt;br/&gt;chat-relay.zap-work.com,43.6532,-79.3832&lt;br/&gt;relay.islandbitcoin.com,12.8498,77.6545&lt;br/&gt;nostr.zoracle.org,45.6018,-121.185&lt;br/&gt;relay-dev.satlantis.io,40.8302,-74.1299&lt;br/&gt;relay.earthly.city,34.0362,-118.443&lt;br/&gt;speakeasy.cellar.social,49.4543,11.0746&lt;br/&gt;relay.bnos.space,43.6532,-79.3832&lt;br/&gt;relay.henryxplace.eu.org:9988,31.2304,121.474&lt;br/&gt;relay.bitmacro.cloud,43.6532,-79.3832&lt;br/&gt;nostr.thebiglake.org,32.71,-96.6745&lt;br/&gt;relay.lab.rytswd.com,49.4543,11.0746&lt;br/&gt;nostr.nadajnik.org,50.1109,8.68213&lt;br/&gt;relay.evanverma.com,40.8302,-74.1299&lt;br/&gt;relay2.angor.io,48.1046,11.6002&lt;br/&gt;prl.plus,55.7628,37.5983&lt;br/&gt;myvoiceourstory.org,37.3598,-121.981&lt;br/&gt;relay.arx-ccn.com,50.4754,12.3683&lt;br/&gt;wot.sudocarlos.com,43.6532,-79.3832&lt;br/&gt;relayrs.notoshi.win,43.6532,-79.3832&lt;br/&gt;nostrcity-club.fly.dev,48.8575,2.35138&lt;br/&gt;relay.tagayasu.xyz,45.4215,-75.6972&lt;br/&gt;nostr.blankfors.se,60.1699,24.9384&lt;br/&gt;nrs-01.darkcloudarcade.com,39.1008,-94.5811&lt;br/&gt;relay.lightning.pub,39.0438,-77.4874&lt;br/&gt;nostr-02.yakihonne.com,1.32123,103.695&lt;br/&gt;relay.nostrverse.net,43.6532,-79.3832&lt;br/&gt;nostr.wecsats.io,43.6532,-79.3832&lt;br/&gt;relay.illuminodes.com,47.6062,-122.332&lt;br/&gt;api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;nostr-relay.psfoundation.info,39.0438,-77.4874&lt;br/&gt;relay.samt.st,40.8302,-74.1299&lt;br/&gt;nostr-relay.cbrx.io,43.6532,-79.3832&lt;br/&gt;inbox.mycelium.social,38.627,-90.1994&lt;br/&gt;relay.anmore.me,49.281,-123.117&lt;br/&gt;no.str.cr,10.074,-84.2155&lt;br/&gt;nstr.a0a1.space,52.3563,4.95714&lt;br/&gt;relay.typedcypher.com,51.5072,-0.127586&lt;br/&gt;relay.bitmacro.pro,43.6532,-79.3832&lt;br/&gt;relay.nostrzh.org,43.6532,-79.3832&lt;br/&gt;ynostr.yael.at,60.1699,24.9384&lt;br/&gt;nostr-relay.zeabur.app,25.0797,121.234&lt;br/&gt;dynasty.libretechsystems.xyz,55.4724,9.87335&lt;br/&gt;nostr.bitcoiner.social,47.6743,-117.112&lt;br/&gt;nostr.girino.org,43.6532,-79.3832&lt;br/&gt;nostr2.girino.org,43.6532,-79.3832&lt;br/&gt;nostr-verified.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.fundstr.me,42.3601,-71.0589&lt;br/&gt;relay.mapboss.co.th,13.7234,100.784&lt;br/&gt;relay.qstr.app,51.5072,-0.127586&lt;br/&gt;nostr-rs-relay-ishosta.phamthanh.me,43.6532,-79.3832&lt;br/&gt;relay.klabo.world,47.674,-122.122&lt;br/&gt;relay.minibolt.info,43.6532,-79.3832&lt;br/&gt;x.kojira.io,43.6532,-79.3832&lt;br/&gt;relay-dev.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostriot.com,41.5695,-83.9786&lt;br/&gt;relayone.soundhsa.com,39.1008,-94.5811&lt;br/&gt;nr.yay.so,46.2126,6.1154&lt;br/&gt;relay.bithome.site,52.3563,4.95714&lt;br/&gt;relay.damus.io,43.6532,-79.3832&lt;br/&gt;nostr.mikoshi.de,50.1109,8.68213&lt;br/&gt;nostr.defucc.me,50.1109,8.68213&lt;br/&gt;relay.malxte.de,52.52,13.405&lt;br/&gt;relay.orangepill.ovh,49.1689,-0.358841&lt;br/&gt;bbw-nostr.xyz,41.5284,-87.4237&lt;br/&gt;kasztanowa.bieda.it,43.6532,-79.3832&lt;br/&gt;bitcoiner.social,47.6743,-117.112&lt;br/&gt;relay.lacompagniemaximus.com,45.3147,-73.8785&lt;br/&gt;relay.mostr.pub,43.6532,-79.3832&lt;br/&gt;relay.lanavault.space,60.1699,24.9384&lt;br/&gt;kotukonostr.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ditto.pub,43.6532,-79.3832&lt;br/&gt;relay.erybody.com,41.4513,-81.7021&lt;br/&gt;nostr.dlcdevkit.com,40.0992,-83.1141&lt;br/&gt;ribo.us.nostria.app,41.5868,-93.625&lt;br/&gt;relay.paulstephenborile.com,49.4543,11.0746&lt;br/&gt;testnet-relay.samt.st,40.8302,-74.1299&lt;br/&gt;relay.purplefrog.cloud,35.6916,139.768&lt;br/&gt;relay.agorist.space,52.3734,4.89406&lt;br/&gt;nostr-relay.zimage.com,34.0549,-118.243&lt;br/&gt;nostr.azzamo.net,52.2633,21.0283&lt;br/&gt;strfry.elswa-dev.online,50.1109,8.68213&lt;br/&gt;wot.shaving.kiwi,43.6532,-79.3832&lt;br/&gt;okn.czas.plus,50.1109,8.68213&lt;br/&gt;bcast.seutoba.com.br,43.6532,-79.3832&lt;br/&gt;relay.sigit.io,50.4754,12.3683&lt;br/&gt;syb.lol,34.0549,-118.243&lt;br/&gt;relay.libernet.app,43.6532,-79.3832&lt;br/&gt;relay.angor.io,48.1046,11.6002&lt;br/&gt;relay.staging.commonshub.brussels,49.4543,11.0746&lt;br/&gt;strfry.atlantislabs.space,43.6532,-79.3832&lt;br/&gt;nostr.wom.wtf,43.6532,-79.3832&lt;br/&gt;nostrride.io,37.3986,-121.964&lt;br/&gt;nostr.dpinkerton.com,39.1008,-94.5811&lt;br/&gt;r.0kb.io,32.789,-96.7989&lt;br/&gt;nostr.hekster.org,37.3986,-121.964&lt;br/&gt;satsage.xyz,37.3986,-121.964&lt;br/&gt;nostr.islandarea.net,35.4669,-97.6473&lt;br/&gt;ve.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.openfarmtools.org,60.1699,24.9384&lt;br/&gt;top.testrelay.top,43.6532,-79.3832&lt;br/&gt;relay-rpi.edufeed.org,49.4521,11.0767&lt;br/&gt;pyramid.cult.cash,32.9483,-96.7299&lt;br/&gt;relay.edino.net,56.6268,47.9193&lt;br/&gt;nostr.snowbla.de,60.1699,24.9384&lt;br/&gt;relay.wavefunc.live,39.7392,-104.99&lt;br/&gt;tenex.chat,50.4754,12.3683&lt;br/&gt;relay.getsafebox.app,43.6532,-79.3832&lt;br/&gt;nostr.bond,50.1109,8.68213&lt;br/&gt;nostrelites.org,41.8781,-87.6298&lt;br/&gt;relay.plebeian.market,50.1109,8.68213&lt;br/&gt;relay.laantungir.net,-19.4692,-42.5315&lt;br/&gt;relay.decentnewsroom.com,50.4754,12.3683&lt;br/&gt;nostr-relay.nextblockvending.com,47.2343,-119.853&lt;br/&gt;relay.spacetomatoes.net,42.3601,-71.0589&lt;br/&gt;nostrbtc.com,43.6532,-79.3832&lt;br/&gt;relay.puresignal.news,43.6532,-79.3832&lt;br/&gt;relay-testnet.k8s.layer3.news,37.3387,-121.885&lt;br/&gt;relay.binaryrobot.com,43.6532,-79.3832&lt;br/&gt;relay.wavlake.com,41.2619,-95.8608&lt;br/&gt;inbox.scuba323.com,40.8218,-74.45&lt;br/&gt;nostr.spaceshell.xyz,43.6532,-79.3832&lt;br/&gt;relay.nostr.place,32.7767,-96.797&lt;br/&gt;holland-excited-charming-experiencing.trycloudflare.com,43.6532,-79.3832&lt;br/&gt;theoutpost.life,64.1476,-21.9392&lt;br/&gt;relay.fckstate.net,59.3293,18.0686&lt;br/&gt;bcast.girino.org,43.6532,-79.3832&lt;br/&gt;discovery.us.nostria.app,52.3676,4.90414&lt;br/&gt;relay.bullishbounty.com,43.6532,-79.3832&lt;br/&gt;nostr.88mph.life,51.5072,-0.127586&lt;br/&gt;nostr.tadryanom.me,43.6532,-79.3832&lt;br/&gt;nostr.sathoarder.com,48.5734,7.75211&lt;br/&gt;relay.nostr.net,43.6532,-79.3832&lt;br/&gt;zw.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.internationalright-wing.org,-22.5022,-48.7114&lt;br/&gt;nostr.vulpem.com,49.4543,11.0746&lt;br/&gt;wot.codingarena.top,50.4754,12.3683&lt;br/&gt;reraw.pbla2fish.cc,43.6532,-79.3832&lt;br/&gt;plebchain.club,43.6532,-79.3832&lt;br/&gt;orly-relay.imwald.eu,48.8575,2.35138&lt;br/&gt;relay.satnam.pub,43.6532,-79.3832&lt;br/&gt;cs-relay.nostrdev.com,50.4754,12.3683&lt;br/&gt;schnorr.me,43.6532,-79.3832&lt;br/&gt;nostr-relay.online,43.6532,-79.3832&lt;br/&gt;relay.routstr.com,43.6532,-79.3832&lt;br/&gt;relay.ohstr.com,43.6532,-79.3832&lt;br/&gt;relay.lanacoin-eternity.com,40.8302,-74.1299&lt;br/&gt;wot.nostr.net,43.6532,-79.3832&lt;br/&gt;nostr.ps1829.com,33.8851,130.883&lt;br/&gt;yabu.me,35.6092,139.73&lt;br/&gt;soloco.nl,43.6532,-79.3832&lt;br/&gt;librerelay.aaroniumii.com,43.6532,-79.3832&lt;br/&gt;relay.mmwaves.de,48.8575,2.35138&lt;br/&gt;relay.artx.market,43.6548,-79.3885&lt;br/&gt;nostr.jerrynya.fun,31.2304,121.474&lt;br/&gt;relay-arg.zombi.cloudrodion.com,1.35208,103.82&lt;br/&gt;relay.edufeed.org,49.4521,11.0767&lt;br/&gt;discovery.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.layer.systems,49.0291,8.35695&lt;br/&gt;nostr-rs-relay.dev.fedibtc.com,39.0438,-77.4874&lt;br/&gt;relay.0xchat.com,43.6532,-79.3832&lt;br/&gt;nos.lol,50.4754,12.3683&lt;br/&gt;lightning.red,53.3498,-6.26031&lt;br/&gt;slick.mjex.me,39.0418,-77.4744&lt;br/&gt;relay.boredvictor.xyz,41.3888,2.15899&lt;br/&gt;nostr.rtvslawenia.com,49.4543,11.0746&lt;br/&gt;relay.mitchelltribe.com,39.0438,-77.4874&lt;br/&gt;nostr.4rs.nl,49.0291,8.35696&lt;br/&gt;relay.olas.app,50.4754,12.3683&lt;br/&gt;memlay.v0l.io,53.3498,-6.26031&lt;br/&gt;nostr-01.yakihonne.com,1.29524,103.79&lt;br/&gt;relay.satmaxt.xyz,43.6532,-79.3832&lt;br/&gt;nostrcheck.tnsor.network,43.6532,-79.3832&lt;br/&gt;relay.guggero.org,46.0037,8.95105&lt;br/&gt;ai.techunder.tech:56711,22.5429,114.06&lt;br/&gt;premium.primal.net,43.6532,-79.3832&lt;br/&gt;nostr.tac.lol,47.4748,-122.273&lt;br/&gt;relay.zone667.com,60.1699,24.9384&lt;br/&gt;nostr-relay.gateway.in.th,15.5163,103.194&lt;br/&gt;vault.iris.to,43.6532,-79.3832&lt;br/&gt;strfry.bonsai.com,37.8716,-122.273&lt;br/&gt;ribo.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.tapestry.ninja,40.8054,-74.0241&lt;br/&gt;relay.dwadziesciajeden.pl,52.2297,21.0122&lt;br/&gt;relay.satlantis.io,32.8769,-80.0114&lt;br/&gt;nostr.pbfs.io,50.4754,12.3683&lt;br/&gt;freelay.sovbit.host,64.1476,-21.9392&lt;br/&gt;articles.layer3.news,37.3387,-121.885&lt;br/&gt;nostr.na.social,43.6532,-79.3832&lt;br/&gt;relay.fountain.fm,43.6532,-79.3832&lt;br/&gt;dev.relay.stream,43.6532,-79.3832&lt;br/&gt;nostr.n7ekb.net,36.1527,-95.9902&lt;br/&gt;relay5.bitransfer.org,43.6532,-79.3832&lt;br/&gt;relay.og.coop,43.6532,-79.3832&lt;br/&gt;nostr-server-production.up.railway.app,45.5019,-73.5674&lt;br/&gt;bucket.coracle.social,37.7775,-122.397&lt;br/&gt;relay.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostr-check.me,43.6532,-79.3832&lt;br/&gt;nostr.faultables.net,43.6532,-79.3832&lt;br/&gt;strfry.openhoofd.nl,51.9229,4.40833&lt;br/&gt;nostr.rblb.it:7777,43.7094,10.6582&lt;br/&gt;relay.nostrcheck.me,43.6532,-79.3832&lt;br/&gt;0x-nostr-relay.fly.dev,48.8575,2.35138&lt;br/&gt;nostr.thalheim.io,60.1699,24.9384&lt;br/&gt;relay-nl.zombi.cloudrodion.com,50.8943,6.06237&lt;br/&gt;relay.shadowbip.com,51.5072,-0.127586&lt;br/&gt;nostr-relay.corb.net,38.8353,-104.822&lt;br/&gt;purplerelay.com,43.6532,-79.3832&lt;br/&gt;nostr-pub.wellorder.net,45.5201,-122.99&lt;br/&gt;herbstmeister.com,34.0549,-118.243&lt;br/&gt;nostrcheck.me,43.6532,-79.3832&lt;br/&gt;pyramid.nostr.technology,52.3947,4.66399&lt;br/&gt;nostr.spicyz.io,43.6532,-79.3832&lt;br/&gt;nrs-02.darkcloudarcade.com,39.9526,-75.1652&lt;br/&gt;nestr.nedao.ch,47.0151,6.98832&lt;br/&gt;nostr.nodesmap.com,59.3327,18.0656&lt;br/&gt;nittom.nostr1.com,38.6327,-90.1961&lt;br/&gt;public.crostr.com,43.6532,-79.3832&lt;br/&gt;relay.cypherflow.ai,48.8575,2.35138&lt;br/&gt;nostr.bitczat.pl,60.1699,24.9384&lt;br/&gt;relayone.geektank.ai,39.1008,-94.5811&lt;br/&gt;testrelay.era21.space,43.6532,-79.3832&lt;br/&gt;relay.npubhaus.com,43.6532,-79.3832&lt;br/&gt;relay.bitmacro.io,48.8566,2.35222&lt;br/&gt;nostr.data.haus,50.4754,12.3683&lt;br/&gt;relay.credenso.cafe,43.3601,-80.3127&lt;br/&gt;relay.ru.ac.th,13.7607,100.627&lt;br/&gt;relay-fra.zombi.cloudrodion.com,48.8566,2.35222&lt;br/&gt;nostr.chaima.info,50.1109,8.68213&lt;br/&gt;nostr.mom,50.4754,12.3683
    </content>
    <updated>2026-04-04T01:44:47Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsdnzyquvfyhyfr6dnp48eu8ap6t5k98u8505ndd56jc87e05rf7tszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjs2ehky</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsdnzyquvfyhyfr6dnp48eu8ap6t5k98u8505ndd56jc87e05rf7tszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjs2ehky" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use get_file_hash_core::{get_git_tracked_files, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event, publish_patch_event};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_patch;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;; // Example commit ID&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use an existing file for the patch content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_patch --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:44:43Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqspm5hyr0e3uvqjwyzwmkguvuscct93hym0ss28jk39yfadklqjgvszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjpl95we</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqspm5hyr0e3uvqjwyzwmkguvuscct93hym0ss28jk39yfadklqjgvszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjpl95we" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use get_file_hash_core::{get_relay_urls, publish_issue, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event, publish_patch_event};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-gnostr-repository-issue-example&amp;#34;; // Repository identifier&lt;br/&gt;    let issue_id_1 = &amp;#34;issue-001&amp;#34;; // Unique identifier for the first issue&lt;br/&gt;    let issue_id_2 = &amp;#34;issue-002&amp;#34;; // Unique identifier for the second issue&lt;br/&gt;    let title_1 = &amp;#34;Bug: Application crashes on startup&amp;#34;;&lt;br/&gt;    let content_1 = &amp;#34;The application fails to launch on macOS Ventura. It throws a &amp;#39;Segmentation Fault&amp;#39; error immediately after execution. This was observed on version `v1.2.3`.&lt;br/&gt;&lt;br/&gt;Steps to reproduce:&lt;br/&gt;1. Download `app-v1.2.3-macos.tar.gz`&lt;br/&gt;2. Extract the archive&lt;br/&gt;3. Run `./app`&lt;br/&gt;&lt;br/&gt;Expected behavior: Application launches successfully.&lt;br/&gt;Actual behavior: Application crashes with &amp;#39;Segmentation Fault&amp;#39;.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    let title_2 = &amp;#34;Feature Request: Dark Mode&amp;#34;;&lt;br/&gt;    let content_2 = &amp;#34;Users have requested a dark mode option to improve readability and reduce eye strain during prolonged use. This should be toggleable in the settings menu.&lt;br/&gt;&lt;br/&gt;Considerations:&lt;br/&gt;- Adherence to system dark mode settings.&lt;br/&gt;- Consistent styling across all UI components.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Publish an issue without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing issue &amp;#39;{}&amp;#39; without build_manifest_event_id...&amp;#34;, title_1);&lt;br/&gt;    publish_issue!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        issue_id_1,&lt;br/&gt;        title_1,&lt;br/&gt;        content_1&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Issue &amp;#39;{}&amp;#39; published.&amp;#34;, title_1);&lt;br/&gt;&lt;br/&gt;    // Example 2: Publish an issue with build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing issue &amp;#39;{}&amp;#39; with build_manifest_event_id...&amp;#34;, title_2);&lt;br/&gt;    publish_issue!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        issue_id_2,&lt;br/&gt;        title_2,&lt;br/&gt;        content_2,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Issue &amp;#39;{}&amp;#39; published.&amp;#34;, title_2);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_issue --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:44:29Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsfda7ct27f7wt3fetgn80vayef7zkjvg94tta49d8939dyu7ea3eczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjt8a5s7</id>
    
      <title type="html">#![cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsfda7ct27f7wt3fetgn80vayef7zkjvg94tta49d8939dyu7ea3eczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjt8a5s7" />
    <content type="html">
      #![cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;use frost::keys::PublicKeyPackage;&lt;br/&gt;use frost::round2::SignatureShare;&lt;br/&gt;use frost::SigningPackage;&lt;br/&gt;use hex;&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;use sha2::Sha256;&lt;br/&gt;use serde_json;&lt;br/&gt;use sha2::Digest;&lt;br/&gt;&lt;br/&gt;pub fn process_relay_share(&lt;br/&gt;    relay_payload_hex: &amp;amp;str,&lt;br/&gt;    signer_id_u16: u16,&lt;br/&gt;    _signing_package: &amp;amp;SigningPackage,&lt;br/&gt;    _pubkey_package: &amp;amp;PublicKeyPackage,&lt;br/&gt;) -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    // In a real scenario, this function would deserialize the share, perform&lt;br/&gt;    // individual verification, and store it for aggregation.&lt;br/&gt;    // For this example, we&amp;#39;ll just acknowledge receipt.&lt;br/&gt;    let _share_bytes = hex::decode(relay_payload_hex)?;&lt;br/&gt;    let _share = SignatureShare::deserialize(&amp;amp;_share_bytes)?;&lt;br/&gt;    let _identifier = frost::Identifier::try_from(signer_id_u16)?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;✅ Share from Signer {} processed (simplified).&amp;#34;, signer_id_u16);&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;pub fn simulate_frost_mailbox_coordinator() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (2, 2);&lt;br/&gt;&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    let signer1_id = frost::Identifier::try_from(1 as u16)?;&lt;br/&gt;    let key_package1: frost::keys::KeyPackage = shares[&amp;amp;signer1_id].clone().try_into()?;&lt;br/&gt;    let signer2_id = frost::Identifier::try_from(2 as u16)?;&lt;br/&gt;    let key_package2: frost::keys::KeyPackage = shares[&amp;amp;signer2_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    let message = b&amp;#34;BIP-64MOD: Anchor Data Proposal v1&amp;#34;;&lt;br/&gt;&lt;br/&gt;    let (nonces1, comms1) = frost::round1::commit(key_package1.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    let (nonces2, comms2) = frost::round1::commit(key_package2.signing_share(), &amp;amp;mut rng);&lt;br/&gt;&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    session_commitments.insert(signer1_id, comms1);&lt;br/&gt;    session_commitments.insert(signer2_id, comms2);&lt;br/&gt;&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments.clone(), message);&lt;br/&gt;&lt;br/&gt;    let share1 = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces1, &amp;amp;key_package1)?;&lt;br/&gt;    let share1_hex = hex::encode(share1.serialize());&lt;br/&gt;&lt;br/&gt;    let share2 = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces2, &amp;amp;key_package2)?;&lt;br/&gt;    let share2_hex = hex::encode(share2.serialize());&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Coordinator listening for Nostr events (simulated)...&amp;#34;);&lt;br/&gt;&lt;br/&gt;    process_relay_share(&amp;amp;share1_hex, 1_u16, &amp;amp;signing_package, &amp;amp;pubkey_package)?;&lt;br/&gt;    process_relay_share(&amp;amp;share2_hex, 2_u16, &amp;amp;signing_package, &amp;amp;pubkey_package)?;&lt;br/&gt;    println!(&amp;#34;All required shares processed. Coordinator would now aggregate.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Simulates a Signer producing a FROST signature share and preparing a Nostr event&lt;br/&gt;/// to be sent to a coordinator via a &amp;#34;mailbox&amp;#34; relay.&lt;br/&gt;///&lt;br/&gt;/// In a real ROAST setup, signers would generate their share and post it&lt;br/&gt;/// encrypted (e.g., using NIP-44) to a coordinator&amp;#39;s &amp;#34;mailbox&amp;#34; on a Nostr relay.&lt;br/&gt;/// This function demonstrates the creation of the signature share and the&lt;br/&gt;/// construction of a *simplified* Nostr event JSON.&lt;br/&gt;///&lt;br/&gt;/// # Arguments&lt;br/&gt;///&lt;br/&gt;/// * `_identifier` - The FROST identifier of the signer. (Currently unused in this specific function body).&lt;br/&gt;/// * `signing_package` - The FROST signing package received from the coordinator.&lt;br/&gt;/// * `nonces` - The signer&amp;#39;s nonces generated in Round 1.&lt;br/&gt;/// * `key_package` - The signer&amp;#39;s FROST key package.&lt;br/&gt;/// * `coordinator_pubkey` - The hex-encoded public key of the ROAST coordinator,&lt;br/&gt;///                          used to tag the Nostr event.&lt;br/&gt;///&lt;br/&gt;/// # Returns&lt;br/&gt;///&lt;br/&gt;/// A `Result` containing the JSON string of the Nostr event if successful,&lt;br/&gt;/// or a `Box&amp;lt;dyn std::error::Error&amp;gt;` if an error occurs.&lt;br/&gt;pub fn create_signer_event(&lt;br/&gt;    _identifier: frost::Identifier,&lt;br/&gt;    signing_package: &amp;amp;frost::SigningPackage,&lt;br/&gt;    nonces: &amp;amp;frost::round1::SigningNonces,&lt;br/&gt;    key_package: &amp;amp;frost::keys::KeyPackage,&lt;br/&gt;    coordinator_pubkey: &amp;amp;str, // The Hex pubkey of the ROAST coordinator&lt;br/&gt;) -&amp;gt; Result&amp;lt;String, Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;&lt;br/&gt;    // 1. Generate the partial signature share (Round 2 of FROST)&lt;br/&gt;    // This share is the core cryptographic output from the signer.&lt;br/&gt;    let share = frost::round2::sign(signing_package, nonces, key_package)?;&lt;br/&gt;    let share_bytes = share.serialize();&lt;br/&gt;    let share_hex = hex::encode(share_bytes);&lt;br/&gt;&lt;br/&gt;    // 2. Create a Session ID to tag the event&lt;br/&gt;    // This ID is derived from the signing package hash, allowing the coordinator&lt;br/&gt;    // to correlate shares belonging to the same signing session.&lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(signing_package.serialize()?);&lt;br/&gt;    let session_id = hex::encode(hasher.finalize());&lt;br/&gt;&lt;br/&gt;    // 3. Construct the Nostr Event JSON (Simplified)&lt;br/&gt;    // This JSON represents the event that a signer would post to a relay.&lt;br/&gt;    // In a production ROAST system, the &amp;#39;content&amp;#39; field (the signature share)&lt;br/&gt;    // would be encrypted for the coordinator using NIP-44.&lt;br/&gt;    let event = serde_json::json!({&lt;br/&gt;        &amp;#34;kind&amp;#34;: 4, // Example: Using Kind 4 (Private Message), though custom Kinds could be used for Sovereign Stack.&lt;br/&gt;        &amp;#34;pubkey&amp;#34;: hex::encode(key_package.verifying_key().serialize()?.as_slice()), // Signer&amp;#39;s public key&lt;br/&gt;        &amp;#34;created_at&amp;#34;: 1712050000, // Example timestamp&lt;br/&gt;        &amp;#34;tags&amp;#34;: [&lt;br/&gt;            [&amp;#34;p&amp;#34;, coordinator_pubkey],       // &amp;#39;p&amp;#39; tag: Directs the event to the coordinator.&lt;br/&gt;            [&amp;#34;i&amp;#34;, session_id],               // &amp;#39;i&amp;#39; tag: Provides a session identifier for filtering/requests.&lt;br/&gt;            [&amp;#34;t&amp;#34;, &amp;#34;frost-signature-share&amp;#34;]   // &amp;#39;t&amp;#39; tag: A searchable label for the event type.&lt;br/&gt;        ],&lt;br/&gt;        &amp;#34;content&amp;#34;: share_hex, // The actual signature share (would be encrypted in production).&lt;br/&gt;        &amp;#34;id&amp;#34;: &amp;#34;...&amp;#34;, // Event ID (filled by relay upon publishing)&lt;br/&gt;        &amp;#34;sig&amp;#34;: &amp;#34;...&amp;#34; // Event signature (filled by relay upon publishing)&lt;br/&gt;    });&lt;br/&gt;&lt;br/&gt;    Ok(event.to_string())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;pub fn simulate_frost_mailbox_post_signer() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    use rand::thread_rng;&lt;br/&gt;    use std::collections::BTreeMap;&lt;br/&gt;    use frost_secp256k1_tr as frost;&lt;br/&gt;&lt;br/&gt;    // This example simulates a single signer&amp;#39;s role in a ROAST mailbox post workflow.&lt;br/&gt;    // The general workflow is:&lt;br/&gt;    // 1. Coordinator sends a request for signatures (e.g., on a BIP-64MOD proposal).&lt;br/&gt;    // 2. Signers receive the proposal, perform local verification.&lt;br/&gt;    // 3. Each signer generates their signature share and posts it (encrypted) to a&lt;br/&gt;    //    Nostr relay, targeting the coordinator&amp;#39;s mailbox.&lt;br/&gt;    // 4. The coordinator collects enough shares to aggregate the final signature.&lt;br/&gt;&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    // For this example, we simulate a 2-of-2 threshold for simplicity.&lt;br/&gt;    let (max_signers, min_signers) = (2, 2);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 1. Key Generation (Simulated Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // In a real distributed setup, this would be DKG. Here, a &amp;#34;trusted dealer&amp;#34;&lt;br/&gt;    // generates the shares and public key package.&lt;br/&gt;    let (shares, _pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // For a 2-of-2 scheme, we have two signers. Let&amp;#39;s pick signer 1.&lt;br/&gt;    let signer1_id = frost::Identifier::try_from(1 as u16)?;&lt;br/&gt;    let key_package1: frost::keys::KeyPackage = shares[&amp;amp;signer1_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    let signer2_id = frost::Identifier::try_from(2 as u16)?;&lt;br/&gt;    let key_package2: frost::keys::KeyPackage = shares[&amp;amp;signer2_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    // The message that is to be signed (e.g., a hash of a Git commit or a Nostr event ID).&lt;br/&gt;    let message = b&amp;#34;This is a test message for ROAST mailbox post.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 2. Round 1: Commitment Phase (Signer&amp;#39;s role)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Each signer generates nonces and commitments.&lt;br/&gt;    let (nonces1, comms1) = frost::round1::commit(key_package1.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    let (nonces2, comms2) = frost::round1::commit(key_package2.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    &lt;br/&gt;    // The coordinator collects these commitments. Here, we simulate by putting them in a BTreeMap.&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    session_commitments.insert(signer1_id, comms1);&lt;br/&gt;    session_commitments.insert(signer2_id, comms2);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 3. Signing Package Creation (Coordinator&amp;#39;s role, simulated for context)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // The coordinator combines the collected commitments and the message to be signed&lt;br/&gt;    // into a signing package, which is then sent back to the signers.&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments, message);&lt;br/&gt;&lt;br/&gt;    // Dummy coordinator public key. In a real scenario, this would be the&lt;br/&gt;    // actual public key of the ROAST coordinator, used for event tagging&lt;br/&gt;    // and encryption (NIP-44).&lt;br/&gt;    let coordinator_pubkey_hex = &amp;#34;0000000000000000000000000000000000000000000000000000000000000001&amp;#34;;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 4. Create the Signer Event (Signer&amp;#39;s role)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // We demonstrate for signer 1. Signer 2 would perform a similar action.&lt;br/&gt;    let event_json_signer1 = create_signer_event(&lt;br/&gt;        signer1_id,&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;nonces1,&lt;br/&gt;        &amp;amp;key_package1,&lt;br/&gt;        coordinator_pubkey_hex,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Generated Nostr Event for Signer 1 Mailbox Post:&lt;br/&gt;{}&amp;#34;, event_json_signer1);&lt;br/&gt;&lt;br/&gt;    // Similarly, Signer 2 would generate their event:&lt;br/&gt;    let event_json_signer2 = create_signer_event(&lt;br/&gt;        signer2_id,&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;nonces2,&lt;br/&gt;        &amp;amp;key_package2,&lt;br/&gt;        coordinator_pubkey_hex,&lt;br/&gt;    )?;&lt;br/&gt;    println!(&amp;#34;Generated Nostr Event for Signer 2 Mailbox Post:&lt;br/&gt;{}&amp;#34;, event_json_signer2);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}
    </content>
    <updated>2026-04-04T01:44:08Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs9atg9a4fflruq80rt8ptawpp305y5lunulxlgqlgtun9k3usnjmqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj72kph2</id>
    
      <title type="html">/// deterministic nostr event build example // deterministic ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs9atg9a4fflruq80rt8ptawpp305y5lunulxlgqlgtun9k3usnjmqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj72kph2" />
    <content type="html">
      /// deterministic nostr event build example&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use get_file_hash_core::{get_git_tracked_files, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use nostr_sdk::{EventBuilder, Keys, Tag, SecretKey};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use std::fs;&lt;br/&gt;&lt;br/&gt;use std::path::PathBuf;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use ::hex;&lt;br/&gt;&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    let manifest_dir = std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap();&lt;br/&gt;    let is_git_repo = std::path::Path::new(&amp;amp;manifest_dir).join(&amp;#34;.git&amp;#34;).exists();&lt;br/&gt;    #[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;	#[allow(unused_mut)]&lt;br/&gt;    let mut git_branch_str = String::new();&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_NAME={}&amp;#34;, env!(&amp;#34;CARGO_PKG_NAME&amp;#34;));&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_VERSION={}&amp;#34;, env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;));&lt;br/&gt;&lt;br/&gt;    if is_git_repo {&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;&lt;br/&gt;        let git_branch_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;--abbrev-ref&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for branch name&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_branch_str = if git_branch_output.status.success() &amp;amp;&amp;amp; !git_branch_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_branch_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git branch command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_branch_output.status, String::from_utf8_lossy(&amp;amp;git_branch_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH={}&amp;#34;, git_branch_str);&lt;br/&gt;    } else {&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH=&amp;#34;);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH=&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=.git/HEAD&amp;#34;);&lt;br/&gt;&lt;br/&gt;    //#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    //let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;    let cargo_toml_hash = get_file_hash!(&amp;#34;../Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_TOML_HASH={}&amp;#34;, cargo_toml_hash);&lt;br/&gt;&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;../src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=LIB_HASH={}&amp;#34;, lib_hash);&lt;br/&gt;&lt;br/&gt;    let build_hash = get_file_hash!(&amp;#34;../build.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=BUILD_HASH={}&amp;#34;, build_hash);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=build.rs&amp;#34;);&lt;br/&gt;    let online_relays_csv_path = PathBuf::from(&amp;amp;manifest_dir).join(&amp;#34;src/get_file_hash_core/src/online_relays_gps.csv&amp;#34;);&lt;br/&gt;    if online_relays_csv_path.exists() {&lt;br/&gt;        println!(&amp;#34;cargo:rerun-if-changed={}&amp;#34;, online_relays_csv_path.to_str().unwrap());&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    if cfg!(not(debug_assertions)) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Nostr feature enabled: Build may take longer due to network operations (publishing events to relays).&amp;#34;);&lt;br/&gt;&lt;br/&gt;        // This code only runs in release builds&lt;br/&gt;        let package_version = std::env::var(&amp;#34;CARGO_PKG_VERSION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;        let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;        if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        let files_to_publish: Vec&amp;lt;String&amp;gt; = get_git_tracked_files(&amp;amp;PathBuf::from(&amp;amp;manifest_dir));&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;        // Create padded_commit_hash&lt;br/&gt;        let padded_commit_hash = format!(&amp;#34;{:0&amp;gt;64}&amp;#34;, &amp;amp;git_commit_hash_str);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=PADDED_COMMIT_HASH={}&amp;#34;, padded_commit_hash);&lt;br/&gt;        // Initialize client and keys once&lt;br/&gt;        let initial_secret_key = SecretKey::parse(&amp;amp;padded_commit_hash).expect(&amp;#34;Failed to create Nostr SecretKey from PADDED_COMMIT_HASH&amp;#34;);&lt;br/&gt;        let initial_keys = Keys::new(initial_secret_key);&lt;br/&gt;        let mut client = nostr_sdk::Client::new(initial_keys.clone());&lt;br/&gt;        let mut relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;        // Add relays to the client&lt;br/&gt;        for relay_url in relay_urls.iter() {&lt;br/&gt;            if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to add relay {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        client.connect().await;&lt;br/&gt;        println!(&amp;#34;cargo:warning=Added and connected to {} relays.&amp;#34;, relay_urls.len());&lt;br/&gt;&lt;br/&gt;        let mut published_event_ids: Vec&amp;lt;Tag&amp;gt; = Vec::new();&lt;br/&gt;        let mut total_bytes_sent: usize = 0;&lt;br/&gt;    &lt;br/&gt;        for file_path_str in &amp;amp;files_to_publish {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Processing file: {}&amp;#34;, file_path_str);&lt;br/&gt;            match fs::read(file_path_str) {&lt;br/&gt;                Ok(bytes) =&amp;gt; {&lt;br/&gt;                    let mut hasher = Sha256::new();&lt;br/&gt;                    hasher.update(&amp;amp;bytes);&lt;br/&gt;                    let result = hasher.finalize();&lt;br/&gt;                    let file_hash_hex = hex::encode(result);&lt;br/&gt;&lt;br/&gt;                    match SecretKey::from_hex(&amp;amp;file_hash_hex.clone()) {&lt;br/&gt;                        Ok(secret_key) =&amp;gt; {&lt;br/&gt;                            let keys = Keys::new(secret_key);&lt;br/&gt;                            let content = String::from_utf8_lossy(&amp;amp;bytes).into_owned();&lt;br/&gt;                            let tags = vec![&lt;br/&gt;                                Tag::parse([&amp;#34;file&amp;#34;, file_path_str].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                                Tag::parse([&amp;#34;version&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                            ];&lt;br/&gt;                            let event_builder = EventBuilder::text_note(content).tags(tags);&lt;br/&gt;&lt;br/&gt;                            if let Some(event_id) = publish_nostr_event_if_release(&amp;amp;mut client, file_hash_hex, keys.clone(), event_builder, &amp;amp;mut relay_urls, file_path_str, &amp;amp;output_dir, &amp;amp;mut total_bytes_sent).await {&lt;br/&gt;                                published_event_ids.push(Tag::event(event_id));&lt;br/&gt;                            }&lt;br/&gt;&lt;br/&gt;                            // Publish metadata event&lt;br/&gt;                            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                                &amp;amp;keys,&lt;br/&gt;                                &amp;amp;relay_urls,&lt;br/&gt;                                DEFAULT_PICTURE_URL,&lt;br/&gt;                                DEFAULT_BANNER_URL,&lt;br/&gt;                                file_path_str,&lt;br/&gt;                            ).await;&lt;br/&gt;                        }&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to derive Nostr secret key for {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                }&lt;br/&gt;                Err(e) =&amp;gt; {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to read file {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        // Create and publish the build_manifest&lt;br/&gt;        if !published_event_ids.is_empty() {&lt;br/&gt;&lt;br/&gt;            //TODO this will be either the default or detected from env vars PRIVATE_KEY&lt;br/&gt;            let keys = Keys::new(SecretKey::from_hex(DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr keys from DEFAULT_GNOSTR_KEY&amp;#34;));&lt;br/&gt;            let cloned_keys = keys.clone();&lt;br/&gt;            let content = format!(&amp;#34;Build manifest for get_file_hash v{}&amp;#34;, package_version);&lt;br/&gt;            let mut tags = vec![&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;            ];&lt;br/&gt;            tags.extend(published_event_ids);&lt;br/&gt;&lt;br/&gt;            let event_builder = EventBuilder::text_note(content.clone()).tags(tags);&lt;br/&gt;&lt;br/&gt;            if let Some(event_id) = publish_nostr_event_if_release(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                hex::encode(Sha256::digest(content.as_bytes())),&lt;br/&gt;                keys,&lt;br/&gt;                event_builder,&lt;br/&gt;                &amp;amp;mut relay_urls,&lt;br/&gt;                &amp;#34;build_manifest.json&amp;#34;,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;mut total_bytes_sent,&lt;br/&gt;            ).await {&lt;br/&gt;&lt;br/&gt;                let build_manifest_event_id = Some(event_id);&lt;br/&gt;&lt;br/&gt;            // Publish metadata event for the build manifest&lt;br/&gt;            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                &amp;amp;cloned_keys, // Use reference to cloned keys here&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                DEFAULT_PICTURE_URL,&lt;br/&gt;                DEFAULT_BANNER_URL,&lt;br/&gt;                &amp;amp;format!(&amp;#34;build_manifest:{}&amp;#34;, package_version),&lt;br/&gt;            ).await;&lt;br/&gt;            let git_commit_hash = &amp;amp;git_commit_hash_str;&lt;br/&gt;            let git_branch = &amp;amp;git_branch_str;&lt;br/&gt;            let repo_url = std::env::var(&amp;#34;CARGO_PKG_REPOSITORY&amp;#34;).unwrap();&lt;br/&gt;            let repo_name = std::env::var(&amp;#34;CARGO_PKG_NAME&amp;#34;).unwrap();&lt;br/&gt;            let repo_description = std::env::var(&amp;#34;CARGO_PKG_DESCRIPTION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;            let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;            if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            let announcement_keys = Keys::new(SecretKey::from_hex(build_manifest_event_id.unwrap().to_hex().as_str()).expect(&amp;#34;Failed to create Nostr keys from build_manifest_event_id&amp;#34;));&lt;br/&gt;            let announcement_pubkey_hex = announcement_keys.public_key().to_string();&lt;br/&gt;&lt;br/&gt;            // Publish NIP-34 Repository Announcement&lt;br/&gt;            if let Some(_event_id) = get_repo_announcement_event(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                &amp;amp;announcement_keys,&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                &amp;amp;repo_url,&lt;br/&gt;                &amp;amp;repo_name,&lt;br/&gt;                &amp;amp;repo_description,&lt;br/&gt;                &amp;amp;git_commit_hash,&lt;br/&gt;                &amp;amp;git_branch,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;announcement_pubkey_hex&lt;br/&gt;            ).await {&lt;br/&gt;                // Successfully published announcement&lt;br/&gt;            }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        println!(&amp;#34;cargo:warning=Total bytes sent to Nostr relays: {} bytes ({} MB)&amp;#34;, total_bytes_sent, total_bytes_sent as f64 / 1024.0 / 1024.0);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:44:08Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqswtk3ngw8z6h9ttnr5sgasqyhulvc0ytsk6keeph0knm3768sehcqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjvtcj3q</id>
    
      <title type="html">#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))] ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqswtk3ngw8z6h9ttnr5sgasqyhulvc0ytsk6keeph0knm3768sehcqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjvtcj3q" />
    <content type="html">
      #[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use std::fs;&lt;br/&gt;    use std::path::PathBuf;&lt;br/&gt;&lt;br/&gt;    let manifest_dir = PathBuf::from(std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap());&lt;br/&gt;    let crate_src_path = manifest_dir.join(&amp;#34;src&amp;#34;).join(&amp;#34;online_relays_gps.csv&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Only download if the file doesn&amp;#39;t exist or is empty&lt;br/&gt;    if !crate_src_path.exists() || fs::metadata(&amp;amp;crate_src_path).map(|m| m.len() == 0).unwrap_or(true) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Downloading online_relays_gps.csv...&amp;#34;);&lt;br/&gt;        let url = &amp;#34;&lt;a href=&#34;https://raw.githubusercontent.com/permissionlesstech/bitchat/main/relays/online_relays_gps.csv&amp;#34&#34;&gt;https://raw.githubusercontent.com/permissionlesstech/bitchat/main/relays/online_relays_gps.csv&amp;#34&lt;/a&gt;;;&lt;br/&gt;        match reqwest::get(url).await {&lt;br/&gt;            Ok(response) =&amp;gt; {&lt;br/&gt;                if response.status().is_success() {&lt;br/&gt;                    match response.text().await {&lt;br/&gt;                        Ok(content) =&amp;gt; {&lt;br/&gt;                            fs::write(&amp;amp;crate_src_path, content).expect(&amp;#34;Unable to write online_relays_gps.csv&amp;#34;);&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Successfully downloaded online_relays_gps.csv to {:?}&amp;#34;, crate_src_path);&lt;br/&gt;                        },&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to get text from response: {}&amp;#34;, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                } else {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to download online_relays_gps.csv: HTTP status {}&amp;#34;, response.status());&lt;br/&gt;                }&lt;br/&gt;            },&lt;br/&gt;            Err(e) =&amp;gt; {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to fetch online_relays_gps.csv: {}&amp;#34;, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;)))]&lt;br/&gt;fn main() {&lt;br/&gt;    // Placeholder for when the nostr feature is not enabled or in debug mode&lt;br/&gt;    println!(&amp;#34;cargo:warning=Skipping online_relays_gps.csv download (nostr feature not enabled or debug mode)&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:43:48Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqstzt7f2ql0mu0wny372js4qj5q80w9m9u4eqnnzmg4ylp9z6x6srszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjcppr80</id>
    
      <title type="html">/// BIP-64MOD &#43; GCC: Complete Git Empty &amp;amp; Genesis Constants ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqstzt7f2ql0mu0wny372js4qj5q80w9m9u4eqnnzmg4ylp9z6x6srszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjcppr80" />
    <content type="html">
      /// BIP-64MOD &#43; GCC: Complete Git Empty &amp;amp; Genesis Constants&lt;br/&gt;/// &lt;br/&gt;/// This module provides the standard cryptographic identifiers for &amp;#34;null&amp;#34;, &lt;br/&gt;/// &amp;#34;empty&amp;#34;, and &amp;#34;genesis&amp;#34; states, including NIP-19 (Bech32) identities.&lt;br/&gt;pub struct GitEmptyState;&lt;br/&gt;&lt;br/&gt;impl GitEmptyState {&lt;br/&gt;    // === NULL REFERENCE (Zero Hash) ===&lt;br/&gt;    pub const NULL_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;0000000000000000000000000000000000000000000000000000000000000000&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // === EMPTY BLOB (Empty File) ===&lt;br/&gt;    pub const BLOB_SHA1: &amp;amp;&amp;#39;static str = &amp;#34;e69de29bb2d1d6434b8b29ae775ad8c2e48c5391&amp;#34;;&lt;br/&gt;    pub const BLOB_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813&amp;#34;;&lt;br/&gt;    pub const BLOB_NSEC: &amp;amp;&amp;#39;static str = &amp;#34;nsec1guaq7npmaz5ndqdzvl3mr6d8mndprp2rdls5ram5jys2xqmjrqfsdzhrp6&amp;#34;;&lt;br/&gt;    pub const BLOB_NPUB: &amp;amp;&amp;#39;static str = &amp;#34;npub180cvv07tjdrghvkyh6964p7w9vsqpf3p05868v399v86p8y6f69sq5fdp0&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // === EMPTY TREE (Empty Directory) ===&lt;br/&gt;    pub const TREE_SHA1: &amp;amp;&amp;#39;static str = &amp;#34;4b825dc642cb6eb9a060e54bf8d69288fbee4904&amp;#34;;&lt;br/&gt;    pub const TREE_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321&amp;#34;;&lt;br/&gt;    pub const TREE_NSEC: &amp;amp;&amp;#39;static str = &amp;#34;nsec1dmceksfzt3fknuwpqn29mrv9a75mq4a48v2tfwde88whfhkv2vsslsc46c&amp;#34;;&lt;br/&gt;    pub const TREE_NPUB: &amp;amp;&amp;#39;static str = &amp;#34;npub1pxmpep6yk7z6p332u9588k0vscg26rv29pynvscg26rv29pynvsq6erdfh&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // === GENESIS COMMIT (DeepSpaceM1 @ Epoch 0) ===&lt;br/&gt;    /// Result of: git commit --allow-empty -m &amp;#39;Initial commit&amp;#39; &lt;br/&gt;    /// With Author/Committer: DeepSpaceM1 &amp;lt;ds_m1@gnostr.org&amp;gt; @ 1970-01-01T00:00:00Z&lt;br/&gt;    pub const GENESIS_AUTHOR_NAME: &amp;amp;&amp;#39;static str = &amp;#34;DeepSpaceM1&amp;#34;;&lt;br/&gt;    pub const GENESIS_AUTHOR_EMAIL: &amp;amp;&amp;#39;static str = &amp;#34;ds_m1@gnostr.org&amp;#34;;&lt;br/&gt;    pub const GENESIS_DATE_UNIX: i64 = 0;&lt;br/&gt;    pub const GENESIS_MESSAGE: &amp;amp;&amp;#39;static str = &amp;#34;Initial commit&amp;#34;;&lt;br/&gt;&lt;br/&gt;    /// The resulting SHA-256 Commit Hash for this specific configuration&lt;br/&gt;    pub const GENESIS_COMMIT_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;e9768652d87e07663479a0ad402513f56d953930b659c2ef389d4d03d3623910&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    /// The NIP-19 Identity associated with the Genesis Commit&lt;br/&gt;    pub const GENESIS_NSEC: &amp;amp;&amp;#39;static str = &amp;#34;nsec1jpxmpep6yk7z6p332u9588k0vscg26rv29pynvscg26rv29pynvsq68at9d&amp;#34;;&lt;br/&gt;    pub const GENESIS_NPUB: &amp;amp;&amp;#39;static str = &amp;#34;npub1pxmpep6yk7z6p332u9588k0vscg26rv29pynvscg26rv29pynvsq6erdfh&amp;#34;;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Helper for constructing the commit object string for hashing&lt;br/&gt;pub mod builders {&lt;br/&gt;    use super::GitEmptyState;&lt;br/&gt;&lt;br/&gt;    pub fn build_genesis_commit_object() -&amp;gt; String {&lt;br/&gt;        format!(&lt;br/&gt;            &amp;#34;tree {}\nauthor {} &amp;lt;{}&amp;gt; {} &#43;0000\ncommitter {} &amp;lt;{}&amp;gt; {} &#43;0000\n\n{}\n&amp;#34;,&lt;br/&gt;            GitEmptyState::TREE_SHA256,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_NAME,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_EMAIL,&lt;br/&gt;            GitEmptyState::GENESIS_DATE_UNIX,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_NAME,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_EMAIL,&lt;br/&gt;            GitEmptyState::GENESIS_DATE_UNIX,&lt;br/&gt;            GitEmptyState::GENESIS_MESSAGE&lt;br/&gt;        )&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;--- BIP-64MOD &#43; GCC Genesis State ---&amp;#34;);&lt;br/&gt;    println!(&amp;#34;Commit Hash: {}&amp;#34;, GitEmptyState::GENESIS_COMMIT_SHA256);&lt;br/&gt;    println!(&amp;#34;Author:      {} &amp;lt;{}&amp;gt;&amp;#34;, GitEmptyState::GENESIS_AUTHOR_NAME, GitEmptyState::GENESIS_AUTHOR_EMAIL);&lt;br/&gt;    println!(&amp;#34;Timestamp:   {}&amp;#34;, GitEmptyState::GENESIS_DATE_UNIX);&lt;br/&gt;    println!(&amp;#34;NSEC:        {}&amp;#34;, GitEmptyState::GENESIS_NSEC);&lt;br/&gt;    &lt;br/&gt;    let object_raw = builders::build_genesis_commit_object();&lt;br/&gt;    println!(&amp;#34;\nRaw Git Commit Object:\n---\n{}---&amp;#34;, object_raw);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:43:48Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs95t0sdwh5axzp8gvwlumccs45dng43gw06tjz2rezmfeq75yrprgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj2kvr5y</id>
    
      <title type="html">[package] name = &amp;#34;get_file_hash_core&amp;#34; version = { ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs95t0sdwh5axzp8gvwlumccs45dng43gw06tjz2rezmfeq75yrprgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj2kvr5y" />
    <content type="html">
      [package]&lt;br/&gt;name = &amp;#34;get_file_hash_core&amp;#34;&lt;br/&gt;version = { workspace = true }&lt;br/&gt;edition = { workspace = true }&lt;br/&gt;description = { workspace = true }&lt;br/&gt;license = { workspace = true }&lt;br/&gt;documentation = { workspace = true }&lt;br/&gt;homepage = { workspace = true }&lt;br/&gt;repository = { workspace = true }&lt;br/&gt;authors = { workspace = true }&lt;br/&gt;&lt;br/&gt;[features]&lt;br/&gt;nostr = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:serde_json&amp;#34;, &amp;#34;dep:sha2&amp;#34;, &amp;#34;dep:hex&amp;#34;, &amp;#34;dep:reqwest&amp;#34;, &amp;#34;dep:tokio&amp;#34;, &amp;#34;dep:csv&amp;#34;, &amp;#34;dep:url&amp;#34;, &amp;#34;dep:frost-secp256k1-tr&amp;#34;, &amp;#34;dep:rand&amp;#34;]&lt;br/&gt;frost = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:serde_json&amp;#34;, &amp;#34;dep:sha2&amp;#34;, &amp;#34;dep:hex&amp;#34;, &amp;#34;dep:reqwest&amp;#34;, &amp;#34;dep:tokio&amp;#34;, &amp;#34;dep:csv&amp;#34;, &amp;#34;dep:url&amp;#34;, &amp;#34;dep:frost-secp256k1-tr&amp;#34;, &amp;#34;dep:rand&amp;#34;]&lt;br/&gt;&lt;br/&gt;[dependencies]&lt;br/&gt;sha2 = { workspace = true, optional = true }&lt;br/&gt;nostr = { workspace = true, optional = true }&lt;br/&gt;serde_json = { workspace = true, optional = true }&lt;br/&gt;nostr-sdk = { workspace = true, optional = true }&lt;br/&gt;hex = { workspace = true, optional = true }&lt;br/&gt;csv = { workspace = true, optional = true }&lt;br/&gt;url = { workspace = true, optional = true }&lt;br/&gt;frost-secp256k1-tr = { workspace = true, optional = true }&lt;br/&gt;rand = { workspace = true, optional = true }&lt;br/&gt;&lt;br/&gt;[dev-dependencies]&lt;br/&gt;sha2 = { workspace = true }&lt;br/&gt;tempfile = { workspace = true }&lt;br/&gt;nostr = { workspace = true }&lt;br/&gt;nostr-sdk = { workspace = true }&lt;br/&gt;serde_json = { workspace = true }&lt;br/&gt;hex = { workspace = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;macros&amp;#34;, &amp;#34;rt-multi-thread&amp;#34;] }&lt;br/&gt;csv = { workspace = true }&lt;br/&gt;url = { workspace = true }&lt;br/&gt;frost-secp256k1-tr = { workspace = true }&lt;br/&gt;serial_test = { workspace = true, features = [&amp;#34;test_logging&amp;#34;] }&lt;br/&gt;log = { workspace = true }&lt;br/&gt;&lt;br/&gt;[build-dependencies]&lt;br/&gt;reqwest = { workspace = true, features = [&amp;#34;json&amp;#34;], optional = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;macros&amp;#34;, &amp;#34;rt-multi-thread&amp;#34;], optional = true }&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:43:31Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsfqen2hxhx974908q5zs5yrl4tyhc3hnk5x8anc82c7gsy0x6dpqqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjfcddsu</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] fn main() -&amp;gt; Result&amp;lt;(), ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsfqen2hxhx974908q5zs5yrl4tyhc3hnk5x8anc82c7gsy0x6dpqqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjfcddsu" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    get_file_hash_core::frost_mailbox_logic::simulate_frost_mailbox_post_signer()&lt;br/&gt;}&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_mailbox_post --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:43:30Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs9mdnwzdxjtntgyqrf6kdxrg5yhnahtqf6lvpy4dwfuygsnpje2hqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjz4aewd</id>
    
      <title type="html">Build manifest for get_file_hash v0.3.3</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs9mdnwzdxjtntgyqrf6kdxrg5yhnahtqf6lvpy4dwfuygsnpje2hqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjz4aewd" />
    <content type="html">
      In reply to &lt;a href=&#39;/nevent1qqsqsy07pt8eg3kqpe524kl8xgmxf4gta4spd683z22uya8kg20tqvg7s6agu&#39;&gt;nevent1q…6agu&lt;/a&gt;&lt;br/&gt;_________________________&lt;br/&gt;&lt;br/&gt;Build manifest for get_file_hash v0.3.3
    </content>
    <updated>2026-04-04T01:43:30Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsqsy07pt8eg3kqpe524kl8xgmxf4gta4spd683z22uya8kg20tqvgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjv6h28g</id>
    
      <title type="html">&amp;lt;?xml version=&amp;#39;1.0&amp;#39; ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsqsy07pt8eg3kqpe524kl8xgmxf4gta4spd683z22uya8kg20tqvgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjv6h28g" />
    <content type="html">
      &amp;lt;?xml version=&amp;#39;1.0&amp;#39; encoding=&amp;#39;windows-1252&amp;#39;?&amp;gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  Copyright (C) 2017 Christopher R. Field.&lt;br/&gt;&lt;br/&gt;  Licensed under the Apache License, Version 2.0 (the &amp;#34;License&amp;#34;);&lt;br/&gt;  you may not use this file except in compliance with the License.&lt;br/&gt;  You may obtain a copy of the License at&lt;br/&gt;&lt;br/&gt;  &lt;a href=&#34;http://www.apache.org/licenses/LICENSE-2.0&#34;&gt;http://www.apache.org/licenses/LICENSE-2.0&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;  Unless required by applicable law or agreed to in writing, software&lt;br/&gt;  distributed under the License is distributed on an &amp;#34;AS IS&amp;#34; BASIS,&lt;br/&gt;  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;br/&gt;  See the License for the specific language governing permissions and&lt;br/&gt;  limitations under the License.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  The &amp;#34;cargo wix&amp;#34; subcommand provides a variety of predefined variables available&lt;br/&gt;  for customization of this template. The values for each variable are set at&lt;br/&gt;  installer creation time. The following variables are available:&lt;br/&gt;&lt;br/&gt;  TargetTriple      = The rustc target triple name.&lt;br/&gt;  TargetEnv         = The rustc target environment. This is typically either&lt;br/&gt;                      &amp;#34;msvc&amp;#34; or &amp;#34;gnu&amp;#34; depending on the toolchain downloaded and&lt;br/&gt;                      installed.&lt;br/&gt;  TargetVendor      = The rustc target vendor. This is typically &amp;#34;pc&amp;#34;, but Rust&lt;br/&gt;                      does support other vendors, like &amp;#34;uwp&amp;#34;.&lt;br/&gt;  CargoTargetBinDir = The complete path to the directory containing the&lt;br/&gt;                      binaries (exes) to include. The default would be&lt;br/&gt;                      &amp;#34;target\release\&amp;#34;. If an explicit rustc target triple is&lt;br/&gt;                      used, i.e. cross-compiling, then the default path would&lt;br/&gt;                      be &amp;#34;target\&amp;lt;CARGO_TARGET&amp;gt;\&amp;lt;CARGO_PROFILE&amp;gt;&amp;#34;,&lt;br/&gt;                      where &amp;#34;&amp;lt;CARGO_TARGET&amp;gt;&amp;#34; is replaced with the &amp;#34;CargoTarget&amp;#34;&lt;br/&gt;                      variable value and &amp;#34;&amp;lt;CARGO_PROFILE&amp;gt;&amp;#34; is replaced with the&lt;br/&gt;                      value from the &amp;#34;CargoProfile&amp;#34; variable. This can also&lt;br/&gt;                      be overridden manually with the &amp;#34;target-bin-dir&amp;#34; flag.&lt;br/&gt;  CargoTargetDir    = The path to the directory for the build artifacts, i.e.&lt;br/&gt;                      &amp;#34;target&amp;#34;.&lt;br/&gt;  CargoProfile      = The cargo profile used to build the binaries&lt;br/&gt;                      (usually &amp;#34;debug&amp;#34; or &amp;#34;release&amp;#34;).&lt;br/&gt;  Version           = The version for the installer. The default is the&lt;br/&gt;                      &amp;#34;Major.Minor.Fix&amp;#34; semantic versioning number of the Rust&lt;br/&gt;                      package.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  Please do not remove these pre-processor If-Else blocks. These are used with&lt;br/&gt;  the `cargo wix` subcommand to automatically determine the installation&lt;br/&gt;  destination for 32-bit versus 64-bit installers. Removal of these lines will&lt;br/&gt;  cause installation errors.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&amp;lt;?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64 ?&amp;gt;&lt;br/&gt;    &amp;lt;?define PlatformProgramFilesFolder = &amp;#34;ProgramFiles64Folder&amp;#34; ?&amp;gt;&lt;br/&gt;&amp;lt;?else ?&amp;gt;&lt;br/&gt;    &amp;lt;?define PlatformProgramFilesFolder = &amp;#34;ProgramFilesFolder&amp;#34; ?&amp;gt;&lt;br/&gt;&amp;lt;?endif ?&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;Wix xmlns=&amp;#39;&lt;a href=&#34;http://schemas.microsoft.com/wix/2006/wi&amp;#39;&amp;gt&#34;&gt;http://schemas.microsoft.com/wix/2006/wi&amp;#39;&amp;gt&lt;/a&gt;;&lt;br/&gt;&lt;br/&gt;    &amp;lt;Product&lt;br/&gt;        Id=&amp;#39;*&amp;#39;&lt;br/&gt;        Name=&amp;#39;get_file_hash&amp;#39;&lt;br/&gt;        UpgradeCode=&amp;#39;DED69220-26E3-4406-B564-7F2B58C56F57&amp;#39;&lt;br/&gt;        Manufacturer=&amp;#39;gnostr admin@gnostr.org&amp;#39;&lt;br/&gt;        Language=&amp;#39;1033&amp;#39;&lt;br/&gt;        Codepage=&amp;#39;1252&amp;#39;&lt;br/&gt;        Version=&amp;#39;$(var.Version)&amp;#39;&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Package Id=&amp;#39;*&amp;#39;&lt;br/&gt;            Keywords=&amp;#39;Installer&amp;#39;&lt;br/&gt;            Description=&amp;#39;A utility crate providing a procedural macro to compute and embed file hashes at compile time.&amp;#39;&lt;br/&gt;            Manufacturer=&amp;#39;gnostr admin@gnostr.org&amp;#39;&lt;br/&gt;            InstallerVersion=&amp;#39;450&amp;#39;&lt;br/&gt;            Languages=&amp;#39;1033&amp;#39;&lt;br/&gt;            Compressed=&amp;#39;yes&amp;#39;&lt;br/&gt;            InstallScope=&amp;#39;perMachine&amp;#39;&lt;br/&gt;            SummaryCodepage=&amp;#39;1252&amp;#39;&lt;br/&gt;            /&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;MajorUpgrade&lt;br/&gt;            Schedule=&amp;#39;afterInstallInitialize&amp;#39;&lt;br/&gt;            DowngradeErrorMessage=&amp;#39;A newer version of [ProductName] is already installed. Setup will now exit.&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Media Id=&amp;#39;1&amp;#39; Cabinet=&amp;#39;media1.cab&amp;#39; EmbedCab=&amp;#39;yes&amp;#39; DiskPrompt=&amp;#39;CD-ROM #1&amp;#39;/&amp;gt;&lt;br/&gt;        &amp;lt;Property Id=&amp;#39;DiskPrompt&amp;#39; Value=&amp;#39;get_file_hash Installation&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Directory Id=&amp;#39;TARGETDIR&amp;#39; Name=&amp;#39;SourceDir&amp;#39;&amp;gt;&lt;br/&gt;            &amp;lt;Directory Id=&amp;#39;$(var.PlatformProgramFilesFolder)&amp;#39; Name=&amp;#39;PFiles&amp;#39;&amp;gt;&lt;br/&gt;                &amp;lt;Directory Id=&amp;#39;APPLICATIONFOLDER&amp;#39; Name=&amp;#39;get_file_hash&amp;#39;&amp;gt;&lt;br/&gt;                    &lt;br/&gt;                    &amp;lt;!--&lt;br/&gt;                      Enabling the license sidecar file in the installer is a four step process:&lt;br/&gt;&lt;br/&gt;                      1. Uncomment the `Component` tag and its contents.&lt;br/&gt;                      2. Change the value for the `Source` attribute in the `File` tag to a path&lt;br/&gt;                         to the file that should be included as the license sidecar file. The path&lt;br/&gt;                         can, and probably should be, relative to this file.&lt;br/&gt;                      3. Change the value for the `Name` attribute in the `File` tag to the&lt;br/&gt;                         desired name for the file when it is installed alongside the `bin` folder&lt;br/&gt;                         in the installation directory. This can be omitted if the desired name is&lt;br/&gt;                         the same as the file name.&lt;br/&gt;                      4. Uncomment the `ComponentRef` tag with the Id attribute value of &amp;#34;License&amp;#34;&lt;br/&gt;                         further down in this file.&lt;br/&gt;                    --&amp;gt;&lt;br/&gt;                    &amp;lt;!--&lt;br/&gt;                    &amp;lt;Component Id=&amp;#39;License&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                        &amp;lt;File Id=&amp;#39;LicenseFile&amp;#39; Name=&amp;#39;ChangeMe&amp;#39; DiskId=&amp;#39;1&amp;#39; Source=&amp;#39;C:\Path\To\File&amp;#39; KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                    &amp;lt;/Component&amp;gt;&lt;br/&gt;                    --&amp;gt;&lt;br/&gt;&lt;br/&gt;                    &amp;lt;Directory Id=&amp;#39;Bin&amp;#39; Name=&amp;#39;bin&amp;#39;&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;Path&amp;#39; Guid=&amp;#39;8DB39A25-8B99-4C25-8CF5-4704353C7C6E&amp;#39; KeyPath=&amp;#39;yes&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;Environment&lt;br/&gt;                                Id=&amp;#39;PATH&amp;#39;&lt;br/&gt;                                Name=&amp;#39;PATH&amp;#39;&lt;br/&gt;                                Value=&amp;#39;[Bin]&amp;#39;&lt;br/&gt;                                Permanent=&amp;#39;no&amp;#39;&lt;br/&gt;                                Part=&amp;#39;last&amp;#39;&lt;br/&gt;                                Action=&amp;#39;set&amp;#39;&lt;br/&gt;                                System=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;binary0&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;File&lt;br/&gt;                                Id=&amp;#39;exe0&amp;#39;&lt;br/&gt;                                Name=&amp;#39;get_file_hash.exe&amp;#39;&lt;br/&gt;                                DiskId=&amp;#39;1&amp;#39;&lt;br/&gt;                                Source=&amp;#39;$(var.CargoTargetBinDir)\get_file_hash.exe&amp;#39;&lt;br/&gt;                                KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;binary1&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;File&lt;br/&gt;                                Id=&amp;#39;exe1&amp;#39;&lt;br/&gt;                                Name=&amp;#39;readme.exe&amp;#39;&lt;br/&gt;                                DiskId=&amp;#39;1&amp;#39;&lt;br/&gt;                                Source=&amp;#39;$(var.CargoTargetBinDir)\readme.exe&amp;#39;&lt;br/&gt;                                KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                    &amp;lt;/Directory&amp;gt;&lt;br/&gt;                &amp;lt;/Directory&amp;gt;&lt;br/&gt;            &amp;lt;/Directory&amp;gt;&lt;br/&gt;        &amp;lt;/Directory&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Feature&lt;br/&gt;            Id=&amp;#39;Binaries&amp;#39;&lt;br/&gt;            Title=&amp;#39;Application&amp;#39;&lt;br/&gt;            Description=&amp;#39;Installs all binaries and the license.&amp;#39;&lt;br/&gt;            Level=&amp;#39;1&amp;#39;&lt;br/&gt;            ConfigurableDirectory=&amp;#39;APPLICATIONFOLDER&amp;#39;&lt;br/&gt;            AllowAdvertise=&amp;#39;no&amp;#39;&lt;br/&gt;            Display=&amp;#39;expand&amp;#39;&lt;br/&gt;            Absent=&amp;#39;disallow&amp;#39;&amp;gt;&lt;br/&gt;            &lt;br/&gt;            &amp;lt;!--&lt;br/&gt;              Uncomment the following `ComponentRef` tag to add the license&lt;br/&gt;              sidecar file to the installer.&lt;br/&gt;            --&amp;gt;&lt;br/&gt;            &amp;lt;!--&amp;lt;ComponentRef Id=&amp;#39;License&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;            &amp;lt;ComponentRef Id=&amp;#39;binary0&amp;#39;/&amp;gt;&lt;br/&gt;            &amp;lt;ComponentRef Id=&amp;#39;binary1&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;            &amp;lt;Feature&lt;br/&gt;                Id=&amp;#39;Environment&amp;#39;&lt;br/&gt;                Title=&amp;#39;PATH Environment Variable&amp;#39;&lt;br/&gt;                Description=&amp;#39;Add the install location of the [ProductName] executable to the PATH system environment variable. This allows the [ProductName] executable to be called from any location.&amp;#39;&lt;br/&gt;                Level=&amp;#39;1&amp;#39;&lt;br/&gt;                Absent=&amp;#39;allow&amp;#39;&amp;gt;&lt;br/&gt;                &amp;lt;ComponentRef Id=&amp;#39;Path&amp;#39;/&amp;gt;&lt;br/&gt;            &amp;lt;/Feature&amp;gt;&lt;br/&gt;        &amp;lt;/Feature&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;SetProperty Id=&amp;#39;ARPINSTALLLOCATION&amp;#39; Value=&amp;#39;[APPLICATIONFOLDER]&amp;#39; After=&amp;#39;CostFinalize&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the following `Icon` and `Property` tags to change the product icon.&lt;br/&gt;&lt;br/&gt;          The product icon is the graphic that appears in the Add/Remove&lt;br/&gt;          Programs control panel for the application.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;Icon Id=&amp;#39;ProductICO&amp;#39; SourceFile=&amp;#39;wix\Product.ico&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;Property Id=&amp;#39;ARPPRODUCTICON&amp;#39; Value=&amp;#39;ProductICO&amp;#39; /&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Property Id=&amp;#39;ARPHELPLINK&amp;#39; Value=&amp;#39;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash&amp;#39;/&amp;gt&#34;&gt;https://github.com/gnostr-org/get_file_hash&amp;#39;/&amp;gt&lt;/a&gt;;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;UI&amp;gt;&lt;br/&gt;            &amp;lt;UIRef Id=&amp;#39;WixUI_FeatureTree&amp;#39;/&amp;gt;&lt;br/&gt;            &lt;br/&gt;            &amp;lt;!--&lt;br/&gt;              Enabling the EULA dialog in the installer is a three step process:&lt;br/&gt;&lt;br/&gt;                1. Comment out or remove the two `Publish` tags that follow the&lt;br/&gt;                   `WixVariable` tag.&lt;br/&gt;                2. Uncomment the `&amp;lt;WixVariable Id=&amp;#39;WixUILicenseRtf&amp;#39; Value=&amp;#39;Path\to\Eula.rft&amp;#39;&amp;gt;` tag further down&lt;br/&gt;                3. Replace the `Value` attribute of the `WixVariable` tag with&lt;br/&gt;                   the path to a RTF file that will be used as the EULA and&lt;br/&gt;                   displayed in the license agreement dialog.&lt;br/&gt;            --&amp;gt;&lt;br/&gt;            &amp;lt;Publish Dialog=&amp;#39;WelcomeDlg&amp;#39; Control=&amp;#39;Next&amp;#39; Event=&amp;#39;NewDialog&amp;#39; Value=&amp;#39;CustomizeDlg&amp;#39; Order=&amp;#39;99&amp;#39;&amp;gt;1&amp;lt;/Publish&amp;gt;&lt;br/&gt;            &amp;lt;Publish Dialog=&amp;#39;CustomizeDlg&amp;#39; Control=&amp;#39;Back&amp;#39; Event=&amp;#39;NewDialog&amp;#39; Value=&amp;#39;WelcomeDlg&amp;#39; Order=&amp;#39;99&amp;#39;&amp;gt;1&amp;lt;/Publish&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;/UI&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Enabling the EULA dialog in the installer requires uncommenting&lt;br/&gt;          the following `WixUILicenseRTF` tag and changing the `Value`&lt;br/&gt;          attribute.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!-- &amp;lt;WixVariable Id=&amp;#39;WixUILicenseRtf&amp;#39; Value=&amp;#39;Relative\Path\to\Eula.rtf&amp;#39;/&amp;gt; --&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the next `WixVariable` tag to customize the installer&amp;#39;s&lt;br/&gt;          Graphical User Interface (GUI) and add a custom banner image across&lt;br/&gt;          the top of each screen. See the WiX Toolset documentation for details&lt;br/&gt;          about customization.&lt;br/&gt;&lt;br/&gt;          The banner BMP dimensions are 493 x 58 pixels.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;WixVariable Id=&amp;#39;WixUIBannerBmp&amp;#39; Value=&amp;#39;wix\Banner.bmp&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the next `WixVariable` tag to customize the installer&amp;#39;s&lt;br/&gt;          Graphical User Interface (GUI) and add a custom image to the first&lt;br/&gt;          dialog, or screen. See the WiX Toolset documentation for details about&lt;br/&gt;          customization.&lt;br/&gt;&lt;br/&gt;          The dialog BMP dimensions are 493 x 312 pixels.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;WixVariable Id=&amp;#39;WixUIDialogBmp&amp;#39; Value=&amp;#39;wix\Dialog.bmp&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;    &amp;lt;/Product&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;/Wix&amp;gt;&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:43:19Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsvslwj3kk7nhq3ss7nfzdw8954lnha7ueaj97g3f58c2vr4q5xcvczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj6cdprr</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsvslwj3kk7nhq3ss7nfzdw8954lnha7ueaj97g3f58c2vr4q5xcvczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj6cdprr" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;use get_file_hash::{BUILD_HASH, CARGO_TOML_HASH, LIB_HASH};&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART0: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use get_file_hash::CARGO_TOML_HASH;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let readme_hash = get_file_hash!(&amp;#34;src/bin/readme.rs&amp;#34;);&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, lib_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/bin/readme.rs is: {}&amp;#34;, readme_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of Cargo.toml is: {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r&amp;#34;## Release&lt;br/&gt;## [`README.md`](./README.md)&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin readme &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## [`src/bin/readme.rs`](src/bin/readme.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/readme.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`build.rs`](build.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `build.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART3: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`Cargo.toml`](Cargo.toml)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `Cargo.toml`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART4: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`src/lib.rs`](src/lib.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/lib.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART_NIP34: &amp;amp;str = r&amp;#34;## NIP-34 Integration: Git Repository Events on Nostr&lt;br/&gt;&lt;br/&gt;This library provides a set of powerful macros and functions for integrating Git repository events with the Nostr protocol, adhering to the [NIP-34: Git Repositories on Nostr](&lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/34.md&#34;&gt;https://github.com/nostr-protocol/nips/blob/master/34.md&lt;/a&gt;) specification.&lt;br/&gt;&lt;br/&gt;These tools allow you to publish various Git-related events to Nostr relays, enabling decentralized tracking and collaboration for your code repositories.&lt;br/&gt;&lt;br/&gt;### Available NIP-34 Macros&lt;br/&gt;&lt;br/&gt;Each macro provides a convenient way to publish specific NIP-34 event kinds:&lt;br/&gt;&lt;br/&gt;*   [`repository_announcement!`](#repository_announcement)&lt;br/&gt;    *   Publishes a `Repository Announcement` event (Kind 30617) to announce a new or updated Git repository.&lt;br/&gt;*   [`publish_patch!`](#publish_patch)&lt;br/&gt;    *   Publishes a `Patch` event (Kind 1617) containing a Git patch (diff) for a specific commit.&lt;br/&gt;*   [`publish_pull_request!`](#publish_pull_request)&lt;br/&gt;    *   Publishes a `Pull Request` event (Kind 1618) to propose changes and facilitate code review.&lt;br/&gt;*   [`publish_pr_update!`](#publish_pr_update)&lt;br/&gt;    *   Publishes a `Pull Request Update` event (Kind 1619) to update an existing pull request.&lt;br/&gt;*   [`publish_repository_state!`](#publish_repository_state)&lt;br/&gt;    *   Publishes a `Repository State` event (Kind 1620) to announce the current state of a branch (e.g., its latest commit).&lt;br/&gt;*   [`publish_issue!`](#publish_issue)&lt;br/&gt;    *   Publishes an `Issue` event (Kind 1621) to report bugs, request features, or track tasks.&lt;br/&gt;&lt;br/&gt;### Running NIP-34 Examples&lt;br/&gt;&lt;br/&gt;To see these macros in action, navigate to the `examples/` directory and run each example individually with the `nostr` feature enabled:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --example repository_announcement --features nostr&lt;br/&gt;cargo run --example publish_patch --features nostr&lt;br/&gt;cargo run --example publish_pull_request --features nostr&lt;br/&gt;cargo run --example publish_pr_update --features nostr&lt;br/&gt;cargo run --example publish_repository_state --features nostr&lt;br/&gt;cargo run --example publish_issue --features nostr&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`readme.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;readme.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    let build_message = if BUILD_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let cargo_message = if CARGO_TOML_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let lib_message = if LIB_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}{}&amp;#34;, README_TEMPLATE_PART0, README_TEMPLATE_PART1, README_TEMPLATE_PART_NIP34);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, BUILD_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, build_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART3);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, cargo_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART4);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, LIB_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, lib_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:43:17Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqspchsuv0aqhdjpue766thpl8zdhq5rd75sspr4qnzymr9r5tvwzrszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjxh7t7t</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] fn main() -&amp;gt; Result&amp;lt;(), ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqspchsuv0aqhdjpue766thpl8zdhq5rd75sspr4qnzymr9r5tvwzrszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjxh7t7t" />
    <content type="html">
      &lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    get_file_hash_core::frost_mailbox_logic::simulate_frost_mailbox_coordinator()&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_mailbox --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:43:17Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsdervfw9yhu6yl4te0u5yja8wz3znzs0hww8tqtue4zm5t096nzpszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj4tfnux</id>
    
      <title type="html">use std::process::Command; use std::fs; use sha2::{Digest, ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsdervfw9yhu6yl4te0u5yja8wz3znzs0hww8tqtue4zm5t096nzpszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj4tfnux" />
    <content type="html">
      use std::process::Command;&lt;br/&gt;use std::fs;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn calculate_sha256(file_path: &amp;amp;str) -&amp;gt; String {&lt;br/&gt;    let content = fs::read(file_path).expect(&amp;#34;Unable to read file&amp;#34;);&lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(&amp;amp;content);&lt;br/&gt;    hasher.finalize()&lt;br/&gt;        .iter()&lt;br/&gt;        .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;        .collect()&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[test]&lt;br/&gt;fn test_get_file_hash_binary_no_features() {&lt;br/&gt;    let output = Command::new(&amp;#34;cargo&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;run&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--bin&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;get_file_hash&amp;#34;)&lt;br/&gt;        .output()&lt;br/&gt;        .expect(&amp;#34;Failed to execute command&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let stdout = String::from_utf8_lossy(&amp;amp;output.stdout);&lt;br/&gt;    let stderr = String::from_utf8_lossy(&amp;amp;output.stderr);&lt;br/&gt;&lt;br/&gt;    // Assert that the command ran successfully&lt;br/&gt;    assert!(output.status.success(), &amp;#34;Command failed with stderr: {}&amp;#34;, stderr);&lt;br/&gt;&lt;br/&gt;    // Manually calculate the hash of the binary&amp;#39;s source file&lt;br/&gt;    let expected_hash = calculate_sha256(&amp;#34;src/bin/get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains the correct hash&lt;br/&gt;    // Check for the raw hash first&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash), &amp;#34;Output did not contain raw expected hash. Expected: {}, Actual: {}&amp;#34;, expected_hash, stdout);&lt;br/&gt;&lt;br/&gt;    // Then check for the formatted string, including backticks&lt;br/&gt;    // Use a regex-like check for more flexibility with newlines if needed, or refine to exact match&lt;br/&gt;    let expected_hash_line = format!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, expected_hash);&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash_line), &amp;#34;Output did not contain expected hash line. Expected line: {}, Actual: {}&amp;#34;, expected_hash_line, stdout);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    assert!(stdout.contains(&amp;#34;Integrity Verified.&amp;#34;), &amp;#34;Output did not contain &amp;#39;Integrity Verified.&amp;#39;. stdout: {}&amp;#34;, stdout);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Output from get_file_hash binary (no features):&lt;br/&gt;{}&amp;#34;, stdout);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[test]&lt;br/&gt;fn test_get_file_hash_binary_with_nostr_feature() {&lt;br/&gt;    let output = Command::new(&amp;#34;cargo&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;run&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--bin&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;get_file_hash&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--features&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;nostr&amp;#34;)&lt;br/&gt;        .output()&lt;br/&gt;        .expect(&amp;#34;Failed to execute command&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let stdout = String::from_utf8_lossy(&amp;amp;output.stdout);&lt;br/&gt;    let stderr = String::from_utf8_lossy(&amp;amp;output.stderr);&lt;br/&gt;&lt;br/&gt;    // Assert that the command ran successfully&lt;br/&gt;    assert!(output.status.success(), &amp;#34;Command failed with stderr: {}&amp;#34;, stderr);&lt;br/&gt;&lt;br/&gt;    // Manually calculate the hash of the binary&amp;#39;s source file&lt;br/&gt;    let expected_hash = calculate_sha256(&amp;#34;src/bin/get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains the correct hash&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash), &amp;#34;Output did not contain raw expected hash. Expected: {}, Actual: {}&amp;#34;, expected_hash, stdout);&lt;br/&gt;&lt;br/&gt;    // Then check for the formatted string, including backticks&lt;br/&gt;    let expected_hash_line = format!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, expected_hash);&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash_line), &amp;#34;Output did not contain expected hash line. Expected line: {}, Actual: {}&amp;#34;, expected_hash_line, stdout);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    assert!(stdout.contains(&amp;#34;Integrity Verified.&amp;#34;), &amp;#34;Output did not contain &amp;#39;Integrity Verified.&amp;#39;. stdout: {}&amp;#34;, stdout);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Output from get_file_hash binary (with nostr feature):&lt;br/&gt;{}&amp;#34;, stdout);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:42:59Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsxfgan2f5ddjnjn9s44xmv7759zk90p8j8zjfpku3mwu6gtnn4ucczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjsn9ex4</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsxfgan2f5ddjnjn9s44xmv7759zk90p8j8zjfpku3mwu6gtnn4ucczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjsn9ex4" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let file_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, file_hash);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;## Setup and Building&lt;br/&gt;&lt;br/&gt;1.  **Clone the repository:**&lt;br/&gt;    ```bash&lt;br/&gt;    git clone &amp;lt;repository-url&amp;gt;&lt;br/&gt;    cd &amp;lt;repository-name&amp;gt;&lt;br/&gt;    ```&lt;br/&gt;2.  **Build the project:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build&lt;br/&gt;    ```&lt;br/&gt;    During the build, `build.rs` will execute and print the hash of `Cargo.toml`.&lt;br/&gt;3.  **Run the example executable:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo run --bin get_file_hash&lt;br/&gt;    ```&lt;br/&gt;    This will print the hash of `src/bin/get_file_hash.rs` to your console.&lt;br/&gt;&lt;br/&gt;## Updating this `README.md`&lt;br/&gt;&lt;br/&gt;The hash information in this `README.md` is automatically generated by running the example executable.&lt;br/&gt;To update it, execute:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin get_file_hash &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## Current File Hash Information (of `src/bin/get_file_hash.rs`)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/get_file_hash.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`get_file_hash.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}&amp;#34;, README_TEMPLATE_PART1, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:42:57Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsqkpwkyvfk57xhzfakk46muru8c2u39vdjhaqrgr7a5s49pn2ny6szyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjctvska</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsqkpwkyvfk57xhzfakk46muru8c2u39vdjhaqrgr7a5s49pn2ny6szyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjctvska" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost; // MUST use the -tr variant for BIP-340/Nostr&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use serde_json::json;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use hex;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (3, 2);&lt;br/&gt;&lt;br/&gt;    // 1. Setup Nostr Event Metadata&lt;br/&gt;    let pubkey_hex = &amp;#34;79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798&amp;#34;; // Example&lt;br/&gt;    let created_at = 1712050000;&lt;br/&gt;    let kind = 1;&lt;br/&gt;    let content = &amp;#34;Hello from ROAST threshold signatures!&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    // 2. Serialize for Nostr ID (per NIP-01)&lt;br/&gt;    let event_json = json!([&lt;br/&gt;        0,&lt;br/&gt;        pubkey_hex,&lt;br/&gt;        created_at,&lt;br/&gt;        kind,&lt;br/&gt;        [],&lt;br/&gt;        content&lt;br/&gt;    ]).to_string();&lt;br/&gt;    &lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(event_json.as_bytes());&lt;br/&gt;    let event_id = hasher.finalize(); // This 32-byte hash is our signing message&lt;br/&gt;&lt;br/&gt;    // 3. FROST/ROAST Key Generation&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // 4. ROAST Coordination Simulation (Round 1: Commitments)&lt;br/&gt;    // In ROAST, the coordinator keeps a &amp;#34;session&amp;#34; open and collects commitments&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    let mut signer_nonces = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    // Signers 1 and 3 respond first (Signer 2 is offline/slow)&lt;br/&gt;    for &amp;amp;id_val in &amp;amp;[1, 3] {&lt;br/&gt;        let id = frost::Identifier::try_from(id_val as u16)?;&lt;br/&gt;        let (nonces, comms) = frost::round1::commit(shares[&amp;amp;id].signing_share(), &amp;amp;mut rng);&lt;br/&gt;        session_commitments.insert(id, comms);&lt;br/&gt;        signer_nonces.insert(id, nonces);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 5. Round 2: Signing the Nostr ID&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments, &amp;amp;event_id);&lt;br/&gt;    let mut signature_shares = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    for (id, nonces) in signer_nonces {&lt;br/&gt;        let key_package: frost::keys::KeyPackage = shares[&amp;amp;id].clone().try_into()?;&lt;br/&gt;        let share = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces, &amp;amp;key_package)?;&lt;br/&gt;        signature_shares.insert(id, share);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 6. Aggregate into a BIP-340 Signature&lt;br/&gt;    let group_signature = frost::aggregate(&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;signature_shares,&lt;br/&gt;        &amp;amp;pubkey_package,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // 7. Verification (using BIP-340 logic)&lt;br/&gt;    pubkey_package.verifying_key().verify(&amp;amp;event_id, &amp;amp;group_signature)?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Nostr Event ID: {}&amp;#34;, hex::encode(event_id));&lt;br/&gt;    println!(&amp;#34;Threshold Signature (BIP-340): {}&amp;#34;, hex::encode(group_signature.serialize()?));&lt;br/&gt;    println!(&amp;#34;Successfully signed Nostr event using ROAST/FROST!&amp;#34;);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_bip_340 --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:42:57Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqszzxvltp0uhpsjnne0m2dln5mk744euywpndykc9ejrhalp5mynmszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj5hsdwl</id>
    
      <title type="html">//! A crate providing the `get_file_hash!` procedural macro. //! ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqszzxvltp0uhpsjnne0m2dln5mk744euywpndykc9ejrhalp5mynmszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj5hsdwl" />
    <content type="html">
      //! A crate providing the `get_file_hash!` procedural macro.&lt;br/&gt;//!&lt;br/&gt;//! This macro allows you to compute the SHA-256 hash of a file at compile time,&lt;br/&gt;//! embedding the resulting hash string directly into your Rust executable.&lt;br/&gt;&lt;br/&gt;pub use get_file_hash_core::get_file_hash;&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `build.rs` at the time of compilation.&lt;br/&gt;pub const BUILD_HASH: &amp;amp;str = env!(&amp;#34;BUILD_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `Cargo.toml` at the time of compilation.&lt;br/&gt;pub const CARGO_TOML_HASH: &amp;amp;str = env!(&amp;#34;CARGO_TOML_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `src/lib.rs` at the time of compilation.&lt;br/&gt;pub const LIB_HASH: &amp;amp;str = env!(&amp;#34;LIB_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The name of the package as specified in Cargo.toml.&lt;br/&gt;pub const CARGO_PKG_NAME: &amp;amp;str = env!(&amp;#34;CARGO_PKG_NAME&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The version of the package as specified in Cargo.toml.&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;/// The git commit hash of the repository at the time of compilation.&lt;br/&gt;pub const GIT_COMMIT_HASH: &amp;amp;str = env!(&amp;#34;GIT_COMMIT_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;/// The git branch of the repository at the time of compilation.&lt;br/&gt;pub const GIT_BRANCH: &amp;amp;str = env!(&amp;#34;GIT_BRANCH&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(test)]&lt;br/&gt;mod tests {&lt;br/&gt;    use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;    use super::*;&lt;br/&gt;&lt;br/&gt;    /// Verifies that the exported CARGO_TOML_HASH is not empty.&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_injected_hash_exists() {&lt;br/&gt;        assert!(!BUILD_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified build.rs Hash:&lt;br/&gt;{}&amp;#34;, BUILD_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_TOML_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Cargo.toml Hash:&lt;br/&gt;{}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!LIB_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified src/lib.rs Hash:\n{}&amp;#34;, LIB_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_PKG_NAME.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Package Name:\n{}&amp;#34;, CARGO_PKG_NAME);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_PKG_VERSION.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Package Version:\n{}&amp;#34;, CARGO_PKG_VERSION);&lt;br/&gt;&lt;br/&gt;        #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;        {&lt;br/&gt;            assert!(!GIT_COMMIT_HASH.is_empty());&lt;br/&gt;            println!(&amp;#34;Verified Git Commit Hash:\n{}&amp;#34;, GIT_COMMIT_HASH);&lt;br/&gt;&lt;br/&gt;            assert!(!GIT_BRANCH.is_empty());&lt;br/&gt;            println!(&amp;#34;Verified Git Branch:\n{}&amp;#34;, GIT_BRANCH);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// Tests that the `get_file_hash!` macro correctly computes the SHA-256&lt;br/&gt;    /// hash of `lib.rs` and that it matches a manually computed hash of the&lt;br/&gt;    /// same file.&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_get_lib_hash() {&lt;br/&gt;        let file_content = include_bytes!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let mut hasher = Sha256::new();&lt;br/&gt;        hasher.update(file_content);&lt;br/&gt;        let expected_hash = hasher&lt;br/&gt;            .finalize()&lt;br/&gt;            .iter()&lt;br/&gt;            .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;            .collect::&amp;lt;String&amp;gt;();&lt;br/&gt;&lt;br/&gt;        let actual_hash = get_file_hash!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;        assert_eq!(actual_hash, expected_hash);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:42:47Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsyn685cfkpdwx4928mm32sy73hccna9pg4r74hmwv9dr3ps5ut8cszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj6feds8</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsyn685cfkpdwx4928mm32sy73hccna9pg4r74hmwv9dr3ps5ut8cszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj6feds8" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let max_signers = 3;&lt;br/&gt;    let min_signers = 2;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 0: Key Generation (Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    // In a real P2P setup, you&amp;#39;d use Distributed Key Generation (DKG).&lt;br/&gt;    // For local testing/simulations, the trusted dealer is faster.&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verifying the public key exists&lt;br/&gt;    let group_public_key = pubkey_package.verifying_key();&lt;br/&gt;    println!(&amp;#34;Group Public Key: {:?}&amp;#34;, group_public_key);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 1: Commitment&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let message = b&amp;#34;BIP-64MOD Consensus Proposal&amp;#34;;&lt;br/&gt;    let mut signing_commitments = BTreeMap::new();&lt;br/&gt;    let mut participant_nonces = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    // Participants 1 and 2 decide to sign&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        &lt;br/&gt;        // Generate nonces and commitments&lt;br/&gt;        let (nonces, commitments) = frost::round1::commit(&lt;br/&gt;            shares[&amp;amp;identifier].signing_share(),&lt;br/&gt;            &amp;amp;mut rng,&lt;br/&gt;        );&lt;br/&gt;        &lt;br/&gt;        signing_commitments.insert(identifier, commitments);&lt;br/&gt;        participant_nonces.insert(identifier, nonces);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 2: Signing&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let mut signature_shares = BTreeMap::new();&lt;br/&gt;    let signing_package = frost::SigningPackage::new(signing_commitments, message);&lt;br/&gt;&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        let nonces = &amp;amp;participant_nonces[&amp;amp;identifier];&lt;br/&gt;        &lt;br/&gt;        // Each participant produces a signature share&lt;br/&gt;        let key_package: frost::keys::KeyPackage = shares[&amp;amp;identifier].clone().try_into()?;&lt;br/&gt;        let share = frost::round2::sign(&amp;amp;signing_package, nonces, &amp;amp;key_package)?;&lt;br/&gt;        signature_shares.insert(identifier, share);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Finalization: Aggregation&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let group_signature = frost::aggregate(&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;signature_shares,&lt;br/&gt;        &amp;amp;pubkey_package,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verification&lt;br/&gt;    group_public_key.verify(message, &amp;amp;group_signature)?;&lt;br/&gt;    &lt;br/&gt;    println!(&amp;#34;Threshold signature verified successfully!&amp;#34;);&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example trusted-dealer --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:42:42Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsxtxqrppf7lyagy53ezwdjwwpz2elksut99p7unq02yk7rnkzzc3gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjlnv5lw</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use rand_chacha::ChaCha20Rng; ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsxtxqrppf7lyagy53ezwdjwwpz2elksut99p7unq02yk7rnkzzc3gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjlnv5lw" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand_chacha::ChaCha20Rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand_chacha::rand_core::SeedableRng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use hex;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost; &lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost::keys::IdentifierList;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    // 1. Create a deterministic seed (e.g., 32 bytes of zeros or a Git Hash)&lt;br/&gt;    let seed_hex = &amp;#34;473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813&amp;#34;;&lt;br/&gt;    let seed_bytes = hex::decode(seed_hex)?;&lt;br/&gt;    let mut rng = ChaCha20Rng::from_seed(seed_bytes.try_into().map_err(|_| &amp;#34;Invalid seed length&amp;#34;)?);&lt;br/&gt;&lt;br/&gt;    let max_signers = 3;&lt;br/&gt;    let min_signers = 2;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 0: Key Generation (Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;&lt;br/&gt;    // Using IdentifierList::Default creates identifiers 1, 2, 3...&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;--- Deterministic FROST Dealer ---&amp;#34;);&lt;br/&gt;    println!(&amp;#34;Threshold: {} of {}&amp;#34;, min_signers, max_signers);&lt;br/&gt;    println!(&amp;#34;Number of shares generated: {}&amp;#34;, shares.len()); &lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;\n--- Verifying Shares Against Commitments ---&amp;#34;);&lt;br/&gt;    for (identifier, share) in &amp;amp;shares {&lt;br/&gt;&lt;br/&gt;        // The Deterministic Values (Scalar Hex)&lt;br/&gt;        // Because your seed is fixed to the EMPTY_BLOB_SHA256,&lt;br/&gt;        // the &amp;#34;redacted&amp;#34; values in your output are always the same.&lt;br/&gt;        // Here are the Secret Signing Shares (the private scalars) for your 2-of-3 setup:&lt;br/&gt;        //&lt;br/&gt;        // Participant,Identifier (x),Signing Share (f(x)) in Hex&lt;br/&gt;        // Participant 1,...0001,757f49553754988450d995c65a0459a0f5a703d7c585f95f468202d09a365f57&lt;br/&gt;        // Participant 2,...0002,a3c4835e32308cb11b43968962290bc9171f1f1ca90c21741890e4f326f9879b&lt;br/&gt;        // Participant 3,...0003,d209bd672d0c80dd65ad974c6a4dc1f138973a618c924988eaaa0715b3bcafdf&lt;br/&gt;        //&lt;br/&gt;        // println!(&amp;#34;Participant Identifier: {:?} {:?}&amp;#34;, identifier, _share);&lt;br/&gt;        //&lt;br/&gt;&lt;br/&gt;        // In FROST, the &amp;#39;verify&amp;#39; method checks the share against the VSS commitment&lt;br/&gt;        match share.verify() {&lt;br/&gt;            Ok(_) =&amp;gt; {&lt;br/&gt;                println!(&amp;#34;Participant {:?}: Valid  ✅&amp;#34;, identifier);&lt;br/&gt;            }&lt;br/&gt;            Err(e) =&amp;gt; {&lt;br/&gt;                println!(&amp;#34;Participant {:?}: INVALID! ❌ Error: {:?}&amp;#34;, identifier, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    let pubkey_bytes = pubkey_package.verifying_key().serialize()?;&lt;br/&gt;    println!(&amp;#34;Group Public Key (Hex Compressed): {}&amp;#34;, hex::encode(&amp;amp;pubkey_bytes));&lt;br/&gt;    let x_only_hex = hex::encode(&amp;amp;pubkey_bytes[1..]);&lt;br/&gt;    println!(&amp;#34;Group Public Key (Hex X-Only):       {}&amp;#34;, x_only_hex);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;Run with --features nostr to enable this example.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:42:40Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs2x95xfdn3j7nssnqwyx6hqsaueatgrvk2zuy2ggx230ned8enm3gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj5a2sd7</id>
    
      <title type="html">Relay URL,Latitude,Longitude wot.nostr.party,36.1627,-86.7816 ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs2x95xfdn3j7nssnqwyx6hqsaueatgrvk2zuy2ggx230ned8enm3gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj5a2sd7" />
    <content type="html">
      Relay URL,Latitude,Longitude&lt;br/&gt;wot.nostr.party,36.1627,-86.7816&lt;br/&gt;nostr.simplex.icu,50.1109,8.68213&lt;br/&gt;relay.snort.social,53.3498,-6.26031&lt;br/&gt;nostr.stakey.net,52.3676,4.90414&lt;br/&gt;relay.mccormick.cx,52.3563,4.95714&lt;br/&gt;nostr.overmind.lol,43.6532,-79.3832&lt;br/&gt;nostriches.club,43.6532,-79.3832&lt;br/&gt;kanagrovv-pyramid.kozow.com,43.4305,-83.9638&lt;br/&gt;relay.toastr.net,40.8054,-74.0241&lt;br/&gt;relay.primal.net,43.6532,-79.3832&lt;br/&gt;r.bitcoinhold.net,43.6532,-79.3832&lt;br/&gt;wot.dtonon.com,43.6532,-79.3832&lt;br/&gt;santo.iguanatech.net,40.8302,-74.1299&lt;br/&gt;relay2.ngengine.org,43.6532,-79.3832&lt;br/&gt;nostr.oxtr.dev,50.4754,12.3683&lt;br/&gt;simplex.icu,50.1109,8.68213&lt;br/&gt;bitchat.nostr1.com,38.6327,-90.1961&lt;br/&gt;relay.nostu.be,40.4167,-3.70329&lt;br/&gt;nostr.mifen.me,43.6532,-79.3832&lt;br/&gt;relay.vantis.ninja,43.6532,-79.3832&lt;br/&gt;nostr-kyomu-haskell.onrender.com,37.7775,-122.397&lt;br/&gt;nostr-relay.amethyst.name,39.0067,-77.4291&lt;br/&gt;relay.bitcoindistrict.org,43.6532,-79.3832&lt;br/&gt;nos.xmark.cc,50.6924,3.20113&lt;br/&gt;relay01.lnfi.network,35.6764,139.65&lt;br/&gt;nostr-dev.wellorder.net,45.5201,-122.99&lt;br/&gt;nostr.rblb.it,43.7094,10.6582&lt;br/&gt;offchain.pub,39.1585,-94.5728&lt;br/&gt;wot.nostr.place,32.7767,-96.797&lt;br/&gt;fanfares.nostr1.com,38.6327,-90.1961&lt;br/&gt;ephemeral.snowflare.cc,43.6532,-79.3832&lt;br/&gt;relay.visionfusen.org,43.6532,-79.3832&lt;br/&gt;nostr.carroarmato0.be,51.0368,3.21186&lt;br/&gt;social.amanah.eblessing.co,48.1046,11.6002&lt;br/&gt;relay.cyphernomad.com,60.4032,25.0321&lt;br/&gt;nostr-rs-relay-qj1h.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ngengine.org,43.6532,-79.3832&lt;br/&gt;relay.nosto.re,51.1792,5.89444&lt;br/&gt;rusty-uat.siberian-albacore.ts.net:8443,35.6764,139.65&lt;br/&gt;nostr.luisschwab.net,43.6532,-79.3832&lt;br/&gt;nostr.aruku.ovh,1.27994,103.849&lt;br/&gt;srtrelay.c-stellar.net,43.6532,-79.3832&lt;br/&gt;nostr.tagomago.me,3.139,101.687&lt;br/&gt;relay.threenine.services,51.5222,-0.62916&lt;br/&gt;nostr.robosats.org,64.1476,-21.9392&lt;br/&gt;nostr.2b9t.xyz,34.0549,-118.243&lt;br/&gt;strfry.apps3.slidestr.net,40.4167,-3.70329&lt;br/&gt;kitchen.zap.cooking,43.6532,-79.3832&lt;br/&gt;relay.homeinhk.xyz,45.5152,-122.678&lt;br/&gt;relay.seq1.net,43.6532,-79.3832&lt;br/&gt;relay.bornheimer.app,50.1109,8.68213&lt;br/&gt;relay.vrtmrz.net,43.6532,-79.3832&lt;br/&gt;nostr.red5d.dev,43.6532,-79.3832&lt;br/&gt;relay-freeharmonypeople.space,38.7223,-9.13934&lt;br/&gt;aaa-api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;dev.relay.edufeed.org,49.4521,11.0767&lt;br/&gt;nostr.myshosholoza.co.za,52.3913,4.66545&lt;br/&gt;nostr.plantroon.com,50.1013,8.62643&lt;br/&gt;wot.dergigi.com,64.1476,-21.9392&lt;br/&gt;npub1spxdug4m3y24hpx5crm0el4zhkk0wafs8kp6m0xu0wecygqej2xqq8gyhx.fips.network,43.6532,-79.3832&lt;br/&gt;nostrelay.circum.space,52.3676,4.90414&lt;br/&gt;relay.dreamith.to,43.6532,-79.3832&lt;br/&gt;relay.nostriches.club,43.6532,-79.3832&lt;br/&gt;nostr-relayrs.gateway.in.th,15.5163,103.194&lt;br/&gt;nostr.chrissexton.org,43.6532,-79.3832&lt;br/&gt;relay.flashapp.me,43.652,-79.3633&lt;br/&gt;nostr-relay-1.trustlessenterprise.com,43.6532,-79.3832&lt;br/&gt;strfry.shock.network,39.0438,-77.4874&lt;br/&gt;relay.snotr.nl:49999,52.0195,4.42946&lt;br/&gt;spatia-arcana.com,34.0362,-118.443&lt;br/&gt;nostr.computingcache.com,34.0356,-118.442&lt;br/&gt;nostr.self-determined.de,53.5,10.25&lt;br/&gt;relay.sharegap.net,43.6532,-79.3832&lt;br/&gt;spookstr2.nostr1.com,38.6327,-90.1961&lt;br/&gt;v-relay.d02.vrtmrz.net,34.6937,135.502&lt;br/&gt;bridge.tagomago.me,3.139,101.687&lt;br/&gt;antiprimal.net,43.6532,-79.3832&lt;br/&gt;relay.nostrdice.com,-33.8688,151.209&lt;br/&gt;purpura.cloud,43.6532,-79.3832&lt;br/&gt;espelho.girino.org,43.6532,-79.3832&lt;br/&gt;relay.mostro.network,40.8302,-74.1299&lt;br/&gt;temp.iris.to,43.6532,-79.3832&lt;br/&gt;pyramid.self-determined.de,53.5,10.25&lt;br/&gt;relay.jeffg.fyi,43.6532,-79.3832&lt;br/&gt;nostr.aruku.kro.kr,37.3589,127.115&lt;br/&gt;chat-relay.zap-work.com,43.6532,-79.3832&lt;br/&gt;relay.islandbitcoin.com,12.8498,77.6545&lt;br/&gt;nostr.zoracle.org,45.6018,-121.185&lt;br/&gt;relay-dev.satlantis.io,40.8302,-74.1299&lt;br/&gt;relay.earthly.city,34.0362,-118.443&lt;br/&gt;speakeasy.cellar.social,49.4543,11.0746&lt;br/&gt;relay.bnos.space,43.6532,-79.3832&lt;br/&gt;relay.henryxplace.eu.org:9988,31.2304,121.474&lt;br/&gt;relay.bitmacro.cloud,43.6532,-79.3832&lt;br/&gt;nostr.thebiglake.org,32.71,-96.6745&lt;br/&gt;relay.lab.rytswd.com,49.4543,11.0746&lt;br/&gt;nostr.nadajnik.org,50.1109,8.68213&lt;br/&gt;relay.evanverma.com,40.8302,-74.1299&lt;br/&gt;relay2.angor.io,48.1046,11.6002&lt;br/&gt;prl.plus,55.7628,37.5983&lt;br/&gt;myvoiceourstory.org,37.3598,-121.981&lt;br/&gt;relay.arx-ccn.com,50.4754,12.3683&lt;br/&gt;wot.sudocarlos.com,43.6532,-79.3832&lt;br/&gt;relayrs.notoshi.win,43.6532,-79.3832&lt;br/&gt;nostrcity-club.fly.dev,48.8575,2.35138&lt;br/&gt;relay.tagayasu.xyz,45.4215,-75.6972&lt;br/&gt;nostr.blankfors.se,60.1699,24.9384&lt;br/&gt;nrs-01.darkcloudarcade.com,39.1008,-94.5811&lt;br/&gt;relay.lightning.pub,39.0438,-77.4874&lt;br/&gt;nostr-02.yakihonne.com,1.32123,103.695&lt;br/&gt;relay.nostrverse.net,43.6532,-79.3832&lt;br/&gt;nostr.wecsats.io,43.6532,-79.3832&lt;br/&gt;relay.illuminodes.com,47.6062,-122.332&lt;br/&gt;api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;nostr-relay.psfoundation.info,39.0438,-77.4874&lt;br/&gt;relay.samt.st,40.8302,-74.1299&lt;br/&gt;nostr-relay.cbrx.io,43.6532,-79.3832&lt;br/&gt;inbox.mycelium.social,38.627,-90.1994&lt;br/&gt;relay.anmore.me,49.281,-123.117&lt;br/&gt;no.str.cr,10.074,-84.2155&lt;br/&gt;nstr.a0a1.space,52.3563,4.95714&lt;br/&gt;relay.typedcypher.com,51.5072,-0.127586&lt;br/&gt;relay.bitmacro.pro,43.6532,-79.3832&lt;br/&gt;relay.nostrzh.org,43.6532,-79.3832&lt;br/&gt;ynostr.yael.at,60.1699,24.9384&lt;br/&gt;nostr-relay.zeabur.app,25.0797,121.234&lt;br/&gt;dynasty.libretechsystems.xyz,55.4724,9.87335&lt;br/&gt;nostr.bitcoiner.social,47.6743,-117.112&lt;br/&gt;nostr.girino.org,43.6532,-79.3832&lt;br/&gt;nostr2.girino.org,43.6532,-79.3832&lt;br/&gt;nostr-verified.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.fundstr.me,42.3601,-71.0589&lt;br/&gt;relay.mapboss.co.th,13.7234,100.784&lt;br/&gt;relay.qstr.app,51.5072,-0.127586&lt;br/&gt;nostr-rs-relay-ishosta.phamthanh.me,43.6532,-79.3832&lt;br/&gt;relay.klabo.world,47.674,-122.122&lt;br/&gt;relay.minibolt.info,43.6532,-79.3832&lt;br/&gt;x.kojira.io,43.6532,-79.3832&lt;br/&gt;relay-dev.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostriot.com,41.5695,-83.9786&lt;br/&gt;relayone.soundhsa.com,39.1008,-94.5811&lt;br/&gt;nr.yay.so,46.2126,6.1154&lt;br/&gt;relay.bithome.site,52.3563,4.95714&lt;br/&gt;relay.damus.io,43.6532,-79.3832&lt;br/&gt;nostr.mikoshi.de,50.1109,8.68213&lt;br/&gt;nostr.defucc.me,50.1109,8.68213&lt;br/&gt;relay.malxte.de,52.52,13.405&lt;br/&gt;relay.orangepill.ovh,49.1689,-0.358841&lt;br/&gt;bbw-nostr.xyz,41.5284,-87.4237&lt;br/&gt;kasztanowa.bieda.it,43.6532,-79.3832&lt;br/&gt;bitcoiner.social,47.6743,-117.112&lt;br/&gt;relay.lacompagniemaximus.com,45.3147,-73.8785&lt;br/&gt;relay.mostr.pub,43.6532,-79.3832&lt;br/&gt;relay.lanavault.space,60.1699,24.9384&lt;br/&gt;kotukonostr.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ditto.pub,43.6532,-79.3832&lt;br/&gt;relay.erybody.com,41.4513,-81.7021&lt;br/&gt;nostr.dlcdevkit.com,40.0992,-83.1141&lt;br/&gt;ribo.us.nostria.app,41.5868,-93.625&lt;br/&gt;relay.paulstephenborile.com,49.4543,11.0746&lt;br/&gt;testnet-relay.samt.st,40.8302,-74.1299&lt;br/&gt;relay.purplefrog.cloud,35.6916,139.768&lt;br/&gt;relay.agorist.space,52.3734,4.89406&lt;br/&gt;nostr-relay.zimage.com,34.0549,-118.243&lt;br/&gt;nostr.azzamo.net,52.2633,21.0283&lt;br/&gt;strfry.elswa-dev.online,50.1109,8.68213&lt;br/&gt;wot.shaving.kiwi,43.6532,-79.3832&lt;br/&gt;okn.czas.plus,50.1109,8.68213&lt;br/&gt;bcast.seutoba.com.br,43.6532,-79.3832&lt;br/&gt;relay.sigit.io,50.4754,12.3683&lt;br/&gt;syb.lol,34.0549,-118.243&lt;br/&gt;relay.libernet.app,43.6532,-79.3832&lt;br/&gt;relay.angor.io,48.1046,11.6002&lt;br/&gt;relay.staging.commonshub.brussels,49.4543,11.0746&lt;br/&gt;strfry.atlantislabs.space,43.6532,-79.3832&lt;br/&gt;nostr.wom.wtf,43.6532,-79.3832&lt;br/&gt;nostrride.io,37.3986,-121.964&lt;br/&gt;nostr.dpinkerton.com,39.1008,-94.5811&lt;br/&gt;r.0kb.io,32.789,-96.7989&lt;br/&gt;nostr.hekster.org,37.3986,-121.964&lt;br/&gt;satsage.xyz,37.3986,-121.964&lt;br/&gt;nostr.islandarea.net,35.4669,-97.6473&lt;br/&gt;ve.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.openfarmtools.org,60.1699,24.9384&lt;br/&gt;top.testrelay.top,43.6532,-79.3832&lt;br/&gt;relay-rpi.edufeed.org,49.4521,11.0767&lt;br/&gt;pyramid.cult.cash,32.9483,-96.7299&lt;br/&gt;relay.edino.net,56.6268,47.9193&lt;br/&gt;nostr.snowbla.de,60.1699,24.9384&lt;br/&gt;relay.wavefunc.live,39.7392,-104.99&lt;br/&gt;tenex.chat,50.4754,12.3683&lt;br/&gt;relay.getsafebox.app,43.6532,-79.3832&lt;br/&gt;nostr.bond,50.1109,8.68213&lt;br/&gt;nostrelites.org,41.8781,-87.6298&lt;br/&gt;relay.plebeian.market,50.1109,8.68213&lt;br/&gt;relay.laantungir.net,-19.4692,-42.5315&lt;br/&gt;relay.decentnewsroom.com,50.4754,12.3683&lt;br/&gt;nostr-relay.nextblockvending.com,47.2343,-119.853&lt;br/&gt;relay.spacetomatoes.net,42.3601,-71.0589&lt;br/&gt;nostrbtc.com,43.6532,-79.3832&lt;br/&gt;relay.puresignal.news,43.6532,-79.3832&lt;br/&gt;relay-testnet.k8s.layer3.news,37.3387,-121.885&lt;br/&gt;relay.binaryrobot.com,43.6532,-79.3832&lt;br/&gt;relay.wavlake.com,41.2619,-95.8608&lt;br/&gt;inbox.scuba323.com,40.8218,-74.45&lt;br/&gt;nostr.spaceshell.xyz,43.6532,-79.3832&lt;br/&gt;relay.nostr.place,32.7767,-96.797&lt;br/&gt;holland-excited-charming-experiencing.trycloudflare.com,43.6532,-79.3832&lt;br/&gt;theoutpost.life,64.1476,-21.9392&lt;br/&gt;relay.fckstate.net,59.3293,18.0686&lt;br/&gt;bcast.girino.org,43.6532,-79.3832&lt;br/&gt;discovery.us.nostria.app,52.3676,4.90414&lt;br/&gt;relay.bullishbounty.com,43.6532,-79.3832&lt;br/&gt;nostr.88mph.life,51.5072,-0.127586&lt;br/&gt;nostr.tadryanom.me,43.6532,-79.3832&lt;br/&gt;nostr.sathoarder.com,48.5734,7.75211&lt;br/&gt;relay.nostr.net,43.6532,-79.3832&lt;br/&gt;zw.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.internationalright-wing.org,-22.5022,-48.7114&lt;br/&gt;nostr.vulpem.com,49.4543,11.0746&lt;br/&gt;wot.codingarena.top,50.4754,12.3683&lt;br/&gt;reraw.pbla2fish.cc,43.6532,-79.3832&lt;br/&gt;plebchain.club,43.6532,-79.3832&lt;br/&gt;orly-relay.imwald.eu,48.8575,2.35138&lt;br/&gt;relay.satnam.pub,43.6532,-79.3832&lt;br/&gt;cs-relay.nostrdev.com,50.4754,12.3683&lt;br/&gt;schnorr.me,43.6532,-79.3832&lt;br/&gt;nostr-relay.online,43.6532,-79.3832&lt;br/&gt;relay.routstr.com,43.6532,-79.3832&lt;br/&gt;relay.ohstr.com,43.6532,-79.3832&lt;br/&gt;relay.lanacoin-eternity.com,40.8302,-74.1299&lt;br/&gt;wot.nostr.net,43.6532,-79.3832&lt;br/&gt;nostr.ps1829.com,33.8851,130.883&lt;br/&gt;yabu.me,35.6092,139.73&lt;br/&gt;soloco.nl,43.6532,-79.3832&lt;br/&gt;librerelay.aaroniumii.com,43.6532,-79.3832&lt;br/&gt;relay.mmwaves.de,48.8575,2.35138&lt;br/&gt;relay.artx.market,43.6548,-79.3885&lt;br/&gt;nostr.jerrynya.fun,31.2304,121.474&lt;br/&gt;relay-arg.zombi.cloudrodion.com,1.35208,103.82&lt;br/&gt;relay.edufeed.org,49.4521,11.0767&lt;br/&gt;discovery.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.layer.systems,49.0291,8.35695&lt;br/&gt;nostr-rs-relay.dev.fedibtc.com,39.0438,-77.4874&lt;br/&gt;relay.0xchat.com,43.6532,-79.3832&lt;br/&gt;nos.lol,50.4754,12.3683&lt;br/&gt;lightning.red,53.3498,-6.26031&lt;br/&gt;slick.mjex.me,39.0418,-77.4744&lt;br/&gt;relay.boredvictor.xyz,41.3888,2.15899&lt;br/&gt;nostr.rtvslawenia.com,49.4543,11.0746&lt;br/&gt;relay.mitchelltribe.com,39.0438,-77.4874&lt;br/&gt;nostr.4rs.nl,49.0291,8.35696&lt;br/&gt;relay.olas.app,50.4754,12.3683&lt;br/&gt;memlay.v0l.io,53.3498,-6.26031&lt;br/&gt;nostr-01.yakihonne.com,1.29524,103.79&lt;br/&gt;relay.satmaxt.xyz,43.6532,-79.3832&lt;br/&gt;nostrcheck.tnsor.network,43.6532,-79.3832&lt;br/&gt;relay.guggero.org,46.0037,8.95105&lt;br/&gt;ai.techunder.tech:56711,22.5429,114.06&lt;br/&gt;premium.primal.net,43.6532,-79.3832&lt;br/&gt;nostr.tac.lol,47.4748,-122.273&lt;br/&gt;relay.zone667.com,60.1699,24.9384&lt;br/&gt;nostr-relay.gateway.in.th,15.5163,103.194&lt;br/&gt;vault.iris.to,43.6532,-79.3832&lt;br/&gt;strfry.bonsai.com,37.8716,-122.273&lt;br/&gt;ribo.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.tapestry.ninja,40.8054,-74.0241&lt;br/&gt;relay.dwadziesciajeden.pl,52.2297,21.0122&lt;br/&gt;relay.satlantis.io,32.8769,-80.0114&lt;br/&gt;nostr.pbfs.io,50.4754,12.3683&lt;br/&gt;freelay.sovbit.host,64.1476,-21.9392&lt;br/&gt;articles.layer3.news,37.3387,-121.885&lt;br/&gt;nostr.na.social,43.6532,-79.3832&lt;br/&gt;relay.fountain.fm,43.6532,-79.3832&lt;br/&gt;dev.relay.stream,43.6532,-79.3832&lt;br/&gt;nostr.n7ekb.net,36.1527,-95.9902&lt;br/&gt;relay5.bitransfer.org,43.6532,-79.3832&lt;br/&gt;relay.og.coop,43.6532,-79.3832&lt;br/&gt;nostr-server-production.up.railway.app,45.5019,-73.5674&lt;br/&gt;bucket.coracle.social,37.7775,-122.397&lt;br/&gt;relay.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostr-check.me,43.6532,-79.3832&lt;br/&gt;nostr.faultables.net,43.6532,-79.3832&lt;br/&gt;strfry.openhoofd.nl,51.9229,4.40833&lt;br/&gt;nostr.rblb.it:7777,43.7094,10.6582&lt;br/&gt;relay.nostrcheck.me,43.6532,-79.3832&lt;br/&gt;0x-nostr-relay.fly.dev,48.8575,2.35138&lt;br/&gt;nostr.thalheim.io,60.1699,24.9384&lt;br/&gt;relay-nl.zombi.cloudrodion.com,50.8943,6.06237&lt;br/&gt;relay.shadowbip.com,51.5072,-0.127586&lt;br/&gt;nostr-relay.corb.net,38.8353,-104.822&lt;br/&gt;purplerelay.com,43.6532,-79.3832&lt;br/&gt;nostr-pub.wellorder.net,45.5201,-122.99&lt;br/&gt;herbstmeister.com,34.0549,-118.243&lt;br/&gt;nostrcheck.me,43.6532,-79.3832&lt;br/&gt;pyramid.nostr.technology,52.3947,4.66399&lt;br/&gt;nostr.spicyz.io,43.6532,-79.3832&lt;br/&gt;nrs-02.darkcloudarcade.com,39.9526,-75.1652&lt;br/&gt;nestr.nedao.ch,47.0151,6.98832&lt;br/&gt;nostr.nodesmap.com,59.3327,18.0656&lt;br/&gt;nittom.nostr1.com,38.6327,-90.1961&lt;br/&gt;public.crostr.com,43.6532,-79.3832&lt;br/&gt;relay.cypherflow.ai,48.8575,2.35138&lt;br/&gt;nostr.bitczat.pl,60.1699,24.9384&lt;br/&gt;relayone.geektank.ai,39.1008,-94.5811&lt;br/&gt;testrelay.era21.space,43.6532,-79.3832&lt;br/&gt;relay.npubhaus.com,43.6532,-79.3832&lt;br/&gt;relay.bitmacro.io,48.8566,2.35222&lt;br/&gt;nostr.data.haus,50.4754,12.3683&lt;br/&gt;relay.credenso.cafe,43.3601,-80.3127&lt;br/&gt;relay.ru.ac.th,13.7607,100.627&lt;br/&gt;relay-fra.zombi.cloudrodion.com,48.8566,2.35222&lt;br/&gt;nostr.chaima.info,50.1109,8.68213&lt;br/&gt;nostr.mom,50.4754,12.3683
    </content>
    <updated>2026-04-04T01:42:36Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs9twkgvyr7xwzj7w00c0fvwzad64zhr2xlj8f2h8c50n580jp3wqszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjs0lsqn</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs9twkgvyr7xwzj7w00c0fvwzad64zhr2xlj8f2h8c50n580jp3wqszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjs0lsqn" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;/// A simplified ROAST Coordinator that manages signing sessions&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;struct RoastCoordinator {&lt;br/&gt;    min_signers: u16,&lt;br/&gt;    _message: Vec&amp;lt;u8&amp;gt;,&lt;br/&gt;    commitments: BTreeMap&amp;lt;frost::Identifier, frost::round1::SigningCommitments&amp;gt;,&lt;br/&gt;    nonces: BTreeMap&amp;lt;frost::Identifier, frost::round1::SigningNonces&amp;gt;,&lt;br/&gt;    shares: BTreeMap&amp;lt;frost::Identifier, frost::round2::SignatureShare&amp;gt;,&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;impl RoastCoordinator {&lt;br/&gt;    fn new(min_signers: u16, message: &amp;amp;[u8]) -&amp;gt; Self {&lt;br/&gt;        Self {&lt;br/&gt;            min_signers,&lt;br/&gt;            _message: message.to_vec(),&lt;br/&gt;            commitments: BTreeMap::new(),&lt;br/&gt;            nonces: BTreeMap::new(),&lt;br/&gt;            shares: BTreeMap::new(),&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// ROAST Logic: Collect commitments until we hit the threshold.&lt;br/&gt;    /// In a real P2P system, this would be an async stream handler.&lt;br/&gt;    fn add_commitment(&amp;amp;mut self, id: frost::Identifier, comms: frost::round1::SigningCommitments, nonces: frost::round1::SigningNonces) {&lt;br/&gt;        if self.commitments.len() &amp;lt; self.min_signers as usize {&lt;br/&gt;            self.commitments.insert(id, comms);&lt;br/&gt;            self.nonces.insert(id, nonces);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// ROAST Logic: Collect signature shares.&lt;br/&gt;    fn add_share(&amp;amp;mut self, id: frost::Identifier, share: frost::round2::SignatureShare) {&lt;br/&gt;        if self.shares.len() &amp;lt; self.min_signers as usize {&lt;br/&gt;            self.shares.insert(id, share);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    fn is_ready_to_sign(&amp;amp;self) -&amp;gt; bool {&lt;br/&gt;        self.commitments.len() &amp;gt;= self.min_signers as usize&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    fn is_ready_to_aggregate(&amp;amp;self) -&amp;gt; bool {&lt;br/&gt;        self.shares.len() &amp;gt;= self.min_signers as usize&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (5, 3);&lt;br/&gt;    let message = b&amp;#34;BIP-64MOD Context: ROAST Coordination&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // 1. Setup: Generate keys (Dealer mode for simulation)&lt;br/&gt;    let (key_shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    let mut coordinator = RoastCoordinator::new(min_signers, message);&lt;br/&gt;&lt;br/&gt;    // 2. Round 1: Asynchronous Commitment Collection&lt;br/&gt;    // Simulate signers 1, 3, and 5 responding first (ROAST skips 2 and 4)&lt;br/&gt;    for &amp;amp;id_num in &amp;amp;[1, 3, 5] {&lt;br/&gt;        let id = frost::Identifier::try_from(id_num as u16)?;&lt;br/&gt;        let (nonces, comms) = frost::round1::commit(key_shares[&amp;amp;id].signing_share(), &amp;amp;mut rng);&lt;br/&gt;        &lt;br/&gt;        // Signers store their nonces locally, send comms to coordinator&lt;br/&gt;        coordinator.add_commitment(id, comms, nonces);&lt;br/&gt;        &lt;br/&gt;        // Note: Signer 2 was &amp;#34;offline&amp;#34;, but ROAST doesn&amp;#39;t care because we hit 3/5.&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 3. Round 2: Signing&lt;br/&gt;    if coordinator.is_ready_to_sign() {&lt;br/&gt;        let signing_package = frost::SigningPackage::new(coordinator.commitments.clone(), message);&lt;br/&gt;        &lt;br/&gt;        let mut temp_shares = BTreeMap::new();&lt;br/&gt;        for &amp;amp;id in coordinator.commitments.keys() {&lt;br/&gt;            // In reality, coordinator sends signing_package to signers&lt;br/&gt;            // Here we simulate the signers producing shares&lt;br/&gt;&lt;br/&gt;            let nonces = &amp;amp;coordinator.nonces[&amp;amp;id];&lt;br/&gt;            &lt;br/&gt;            let key_package: frost::keys::KeyPackage = key_shares[&amp;amp;id].clone().try_into()?;&lt;br/&gt;            let share = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces, &amp;amp;key_package)?;&lt;br/&gt;            temp_shares.insert(id, share);&lt;br/&gt;        }&lt;br/&gt;        for (id, share) in temp_shares {&lt;br/&gt;            coordinator.add_share(id, share);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 4. Finalization: Aggregation&lt;br/&gt;    if coordinator.is_ready_to_aggregate() {&lt;br/&gt;        let signing_package = frost::SigningPackage::new(coordinator.commitments.clone(), message);&lt;br/&gt;        let group_signature = frost::aggregate(&lt;br/&gt;            &amp;amp;signing_package,&lt;br/&gt;            &amp;amp;coordinator.shares,&lt;br/&gt;            &amp;amp;pubkey_package,&lt;br/&gt;        )?;&lt;br/&gt;&lt;br/&gt;        pubkey_package.verifying_key().verify(message, &amp;amp;group_signature)?;&lt;br/&gt;        println!(&amp;#34;ROAST-coordinated signature verified!&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example roast-experiment --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:42:21Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs83rhnckjkcx09nfcgc45e96vttw3nre9z04lqakhkawcy5x5zgzgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjrxntd6</id>
    
      <title type="html"># dist plan --output-format=json &amp;gt; plan-dist-manifest.json # ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs83rhnckjkcx09nfcgc45e96vttw3nre9z04lqakhkawcy5x5zgzgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjrxntd6" />
    <content type="html">
      # dist plan --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;# Config for &amp;#39;dist&amp;#39;&lt;br/&gt;[workspace]&lt;br/&gt;members = [&amp;#34;cargo:.&amp;#34;, &amp;#34;cargo:src/get_file_hash_core&amp;#34;]&lt;br/&gt;&lt;br/&gt;# Config for &amp;#39;dist&amp;#39;&lt;br/&gt;[dist]&lt;br/&gt;# The preferred dist version to use in CI (Cargo.toml SemVer syntax)&lt;br/&gt;cargo-dist-version = &amp;#34;0.30.3&amp;#34;&lt;br/&gt;# CI backends to support&lt;br/&gt;ci = &amp;#34;github&amp;#34;&lt;br/&gt;# The installers to generate for each app&lt;br/&gt;installers = [&amp;#34;shell&amp;#34;, &amp;#34;powershell&amp;#34;, &amp;#34;homebrew&amp;#34;, &amp;#34;msi&amp;#34;]&lt;br/&gt;# A GitHub repo to push Homebrew formulas to&lt;br/&gt;tap = &amp;#34;gnostr-org/homebrew-gnostr-org&amp;#34;&lt;br/&gt;# Path that installers should place binaries in&lt;br/&gt;install-path = &amp;#34;CARGO_HOME&amp;#34;&lt;br/&gt;# Publish jobs to run in CI&lt;br/&gt;publish-jobs = [&amp;#34;homebrew&amp;#34;]&lt;br/&gt;# Whether to install an updater program&lt;br/&gt;install-updater = true&lt;br/&gt;# Target platforms to build apps for (Rust target-triple syntax)&lt;br/&gt;targets = [&amp;#34;aarch64-apple-darwin&amp;#34;, &amp;#34;aarch64-unknown-linux-gnu&amp;#34;, &amp;#34;x86_64-apple-darwin&amp;#34;, &amp;#34;x86_64-unknown-linux-gnu&amp;#34;, &amp;#34;x86_64-unknown-linux-musl&amp;#34;, &amp;#34;x86_64-pc-windows-msvc&amp;#34;]&lt;br/&gt;# Skip checking whether the specified configuration files are up to date&lt;br/&gt;allow-dirty = [&amp;#34;ci&amp;#34;]&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:42:20Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsgv8tu5sz2p0nm9a3hvwxk29smnrlfalfn4e5vqm2nck4gdnlckvczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjzsw80n</id>
    
      <title type="html">Build manifest for get_file_hash v0.3.3</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsgv8tu5sz2p0nm9a3hvwxk29smnrlfalfn4e5vqm2nck4gdnlckvczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjzsw80n" />
    <content type="html">
      In reply to &lt;a href=&#39;/nevent1qqspld4zt6n6w9cuuhp8ss8f9k0pfuljk3rr5zuqrrq2uudhtpx06ysyurujc&#39;&gt;nevent1q…rujc&lt;/a&gt;&lt;br/&gt;_________________________&lt;br/&gt;&lt;br/&gt;Build manifest for get_file_hash v0.3.3
    </content>
    <updated>2026-04-04T01:42:09Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsxrte3a86x4fsc78slnlmavgt7s92m3zucptcch05ac8j74j3nwtgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjyp8zk6</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsxrte3a86x4fsc78slnlmavgt7s92m3zucptcch05ac8j74j3nwtgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjyp8zk6" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[allow(unused_imports)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::repository_announcement;&lt;br/&gt;    use get_file_hash_core::get_file_hash;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use sha2::{Digest, Sha256};&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let project_name = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let description = &amp;#34;A fantastic new project example.&amp;#34;;&lt;br/&gt;    let clone_url = &amp;#34;git@github.com:user/my-awesome-repo-example.git&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing repository announcement without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    repository_announcement!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        project_name,&lt;br/&gt;        description,&lt;br/&gt;        clone_url,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use a known file in your project&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository announcement without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing repository announcement with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    repository_announcement!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        project_name,&lt;br/&gt;        description,&lt;br/&gt;        clone_url,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use a known file in your project&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository announcement with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example repository_announcement --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:42:09Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs9zqu4j96u8genlj5h0e5medeef6zth9uznsz35dqycs20r6702zczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjyl644c</id>
    
      <title type="html">/// deterministic nostr event build example // deterministic ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs9zqu4j96u8genlj5h0e5medeef6zth9uznsz35dqycs20r6702zczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjyl644c" />
    <content type="html">
      /// deterministic nostr event build example&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use get_file_hash_core::{get_git_tracked_files, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use nostr_sdk::{EventBuilder, Keys, Tag, SecretKey};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use std::fs;&lt;br/&gt;&lt;br/&gt;use std::path::PathBuf;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use ::hex;&lt;br/&gt;&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    let manifest_dir = std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap();&lt;br/&gt;    let is_git_repo = std::path::Path::new(&amp;amp;manifest_dir).join(&amp;#34;.git&amp;#34;).exists();&lt;br/&gt;    #[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;	#[allow(unused_mut)]&lt;br/&gt;    let mut git_branch_str = String::new();&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_NAME={}&amp;#34;, env!(&amp;#34;CARGO_PKG_NAME&amp;#34;));&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_VERSION={}&amp;#34;, env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;));&lt;br/&gt;&lt;br/&gt;    if is_git_repo {&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;&lt;br/&gt;        let git_branch_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;--abbrev-ref&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for branch name&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_branch_str = if git_branch_output.status.success() &amp;amp;&amp;amp; !git_branch_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_branch_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git branch command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_branch_output.status, String::from_utf8_lossy(&amp;amp;git_branch_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH={}&amp;#34;, git_branch_str);&lt;br/&gt;    } else {&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH=&amp;#34;);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH=&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=.git/HEAD&amp;#34;);&lt;br/&gt;&lt;br/&gt;    //#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    //let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;    let cargo_toml_hash = get_file_hash!(&amp;#34;Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_TOML_HASH={}&amp;#34;, cargo_toml_hash);&lt;br/&gt;&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=LIB_HASH={}&amp;#34;, lib_hash);&lt;br/&gt;&lt;br/&gt;    let build_hash = get_file_hash!(&amp;#34;build.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=BUILD_HASH={}&amp;#34;, build_hash);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=build.rs&amp;#34;);&lt;br/&gt;    let online_relays_csv_path = PathBuf::from(&amp;amp;manifest_dir).join(&amp;#34;src/get_file_hash_core/src/online_relays_gps.csv&amp;#34;);&lt;br/&gt;    if online_relays_csv_path.exists() {&lt;br/&gt;        println!(&amp;#34;cargo:rerun-if-changed={}&amp;#34;, online_relays_csv_path.to_str().unwrap());&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    if cfg!(not(debug_assertions)) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Nostr feature enabled: Build may take longer due to network operations (publishing events to relays).&amp;#34;);&lt;br/&gt;&lt;br/&gt;        // This code only runs in release builds&lt;br/&gt;        let package_version = std::env::var(&amp;#34;CARGO_PKG_VERSION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;        let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;        if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        let files_to_publish: Vec&amp;lt;String&amp;gt; = get_git_tracked_files(&amp;amp;PathBuf::from(&amp;amp;manifest_dir));&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;        // Create padded_commit_hash&lt;br/&gt;        let padded_commit_hash = format!(&amp;#34;{:0&amp;gt;64}&amp;#34;, &amp;amp;git_commit_hash_str);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=PADDED_COMMIT_HASH={}&amp;#34;, padded_commit_hash);&lt;br/&gt;        // Initialize client and keys once&lt;br/&gt;        let initial_secret_key = SecretKey::parse(&amp;amp;padded_commit_hash).expect(&amp;#34;Failed to create Nostr SecretKey from PADDED_COMMIT_HASH&amp;#34;);&lt;br/&gt;        let initial_keys = Keys::new(initial_secret_key);&lt;br/&gt;        let mut client = nostr_sdk::Client::new(initial_keys.clone());&lt;br/&gt;        let mut relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;        // Add relays to the client&lt;br/&gt;        for relay_url in relay_urls.iter() {&lt;br/&gt;            if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to add relay {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        client.connect().await;&lt;br/&gt;        println!(&amp;#34;cargo:warning=Added and connected to {} relays.&amp;#34;, relay_urls.len());&lt;br/&gt;&lt;br/&gt;        let mut published_event_ids: Vec&amp;lt;Tag&amp;gt; = Vec::new();&lt;br/&gt;        let mut total_bytes_sent: usize = 0;&lt;br/&gt;    &lt;br/&gt;        for file_path_str in &amp;amp;files_to_publish {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Processing file: {}&amp;#34;, file_path_str);&lt;br/&gt;            match fs::read(file_path_str) {&lt;br/&gt;                Ok(bytes) =&amp;gt; {&lt;br/&gt;                    let mut hasher = Sha256::new();&lt;br/&gt;                    hasher.update(&amp;amp;bytes);&lt;br/&gt;                    let result = hasher.finalize();&lt;br/&gt;                    let file_hash_hex = hex::encode(result);&lt;br/&gt;&lt;br/&gt;                    match SecretKey::from_hex(&amp;amp;file_hash_hex.clone()) {&lt;br/&gt;                        Ok(secret_key) =&amp;gt; {&lt;br/&gt;                            let keys = Keys::new(secret_key);&lt;br/&gt;                            let content = String::from_utf8_lossy(&amp;amp;bytes).into_owned();&lt;br/&gt;                            let tags = vec![&lt;br/&gt;                                Tag::parse([&amp;#34;file&amp;#34;, file_path_str].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                                Tag::parse([&amp;#34;version&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                            ];&lt;br/&gt;                            let event_builder = EventBuilder::text_note(content).tags(tags);&lt;br/&gt;&lt;br/&gt;                            if let Some(event_id) = publish_nostr_event_if_release(&amp;amp;mut client, file_hash_hex, keys.clone(), event_builder, &amp;amp;mut relay_urls, file_path_str, &amp;amp;output_dir, &amp;amp;mut total_bytes_sent).await {&lt;br/&gt;                                published_event_ids.push(Tag::event(event_id));&lt;br/&gt;                            }&lt;br/&gt;&lt;br/&gt;                            // Publish metadata event&lt;br/&gt;                            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                                &amp;amp;keys,&lt;br/&gt;                                &amp;amp;relay_urls,&lt;br/&gt;                                DEFAULT_PICTURE_URL,&lt;br/&gt;                                DEFAULT_BANNER_URL,&lt;br/&gt;                                file_path_str,&lt;br/&gt;                            ).await;&lt;br/&gt;                        }&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to derive Nostr secret key for {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                }&lt;br/&gt;                Err(e) =&amp;gt; {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to read file {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        // Create and publish the build_manifest&lt;br/&gt;        if !published_event_ids.is_empty() {&lt;br/&gt;&lt;br/&gt;            //TODO this will be either the default or detected from env vars PRIVATE_KEY&lt;br/&gt;            let keys = Keys::new(SecretKey::from_hex(DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr keys from DEFAULT_GNOSTR_KEY&amp;#34;));&lt;br/&gt;            let cloned_keys = keys.clone();&lt;br/&gt;            let content = format!(&amp;#34;Build manifest for get_file_hash v{}&amp;#34;, package_version);&lt;br/&gt;            let mut tags = vec![&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;            ];&lt;br/&gt;            tags.extend(published_event_ids);&lt;br/&gt;&lt;br/&gt;            let event_builder = EventBuilder::text_note(content.clone()).tags(tags);&lt;br/&gt;&lt;br/&gt;            if let Some(event_id) = publish_nostr_event_if_release(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                hex::encode(Sha256::digest(content.as_bytes())),&lt;br/&gt;                keys,&lt;br/&gt;                event_builder,&lt;br/&gt;                &amp;amp;mut relay_urls,&lt;br/&gt;                &amp;#34;build_manifest.json&amp;#34;,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;mut total_bytes_sent,&lt;br/&gt;            ).await {&lt;br/&gt;&lt;br/&gt;                let build_manifest_event_id = Some(event_id);&lt;br/&gt;&lt;br/&gt;            // Publish metadata event for the build manifest&lt;br/&gt;            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                &amp;amp;cloned_keys, // Use reference to cloned keys here&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                DEFAULT_PICTURE_URL,&lt;br/&gt;                DEFAULT_BANNER_URL,&lt;br/&gt;                &amp;amp;format!(&amp;#34;build_manifest:{}&amp;#34;, package_version),&lt;br/&gt;            ).await;&lt;br/&gt;            let git_commit_hash = &amp;amp;git_commit_hash_str;&lt;br/&gt;            let git_branch = &amp;amp;git_branch_str;&lt;br/&gt;            let repo_url = std::env::var(&amp;#34;CARGO_PKG_REPOSITORY&amp;#34;).unwrap();&lt;br/&gt;            let repo_name = std::env::var(&amp;#34;CARGO_PKG_NAME&amp;#34;).unwrap();&lt;br/&gt;            let repo_description = std::env::var(&amp;#34;CARGO_PKG_DESCRIPTION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;            let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;            if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            let announcement_keys = Keys::new(SecretKey::from_hex(build_manifest_event_id.unwrap().to_hex().as_str()).expect(&amp;#34;Failed to create Nostr keys from build_manifest_event_id&amp;#34;));&lt;br/&gt;            let announcement_pubkey_hex = announcement_keys.public_key().to_string();&lt;br/&gt;&lt;br/&gt;            // Publish NIP-34 Repository Announcement&lt;br/&gt;            if let Some(_event_id) = get_repo_announcement_event(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                &amp;amp;announcement_keys,&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                &amp;amp;repo_url,&lt;br/&gt;                &amp;amp;repo_name,&lt;br/&gt;                &amp;amp;repo_description,&lt;br/&gt;                &amp;amp;git_commit_hash,&lt;br/&gt;                &amp;amp;git_branch,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;announcement_pubkey_hex&lt;br/&gt;            ).await {&lt;br/&gt;                // Successfully published announcement&lt;br/&gt;            }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        println!(&amp;#34;cargo:warning=Total bytes sent to Nostr relays: {} bytes ({} MB)&amp;#34;, total_bytes_sent, total_bytes_sent as f64 / 1024.0 / 1024.0);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:42:06Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs06qw9fwrqfypxpmncqzksd0y4w50a9t5hw3xgv2w50satqggle3qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjf4qzvx</id>
    
      <title type="html">#![cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs06qw9fwrqfypxpmncqzksd0y4w50a9t5hw3xgv2w50satqggle3qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjf4qzvx" />
    <content type="html">
      #![cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;use frost::keys::PublicKeyPackage;&lt;br/&gt;use frost::round2::SignatureShare;&lt;br/&gt;use frost::SigningPackage;&lt;br/&gt;use hex;&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;use sha2::Sha256;&lt;br/&gt;use serde_json;&lt;br/&gt;use sha2::Digest;&lt;br/&gt;&lt;br/&gt;pub fn process_relay_share(&lt;br/&gt;    relay_payload_hex: &amp;amp;str,&lt;br/&gt;    signer_id_u16: u16,&lt;br/&gt;    _signing_package: &amp;amp;SigningPackage,&lt;br/&gt;    _pubkey_package: &amp;amp;PublicKeyPackage,&lt;br/&gt;) -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    // In a real scenario, this function would deserialize the share, perform&lt;br/&gt;    // individual verification, and store it for aggregation.&lt;br/&gt;    // For this example, we&amp;#39;ll just acknowledge receipt.&lt;br/&gt;    let _share_bytes = hex::decode(relay_payload_hex)?;&lt;br/&gt;    let _share = SignatureShare::deserialize(&amp;amp;_share_bytes)?;&lt;br/&gt;    let _identifier = frost::Identifier::try_from(signer_id_u16)?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;✅ Share from Signer {} processed (simplified).&amp;#34;, signer_id_u16);&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;pub fn simulate_frost_mailbox_coordinator() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (2, 2);&lt;br/&gt;&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    let signer1_id = frost::Identifier::try_from(1 as u16)?;&lt;br/&gt;    let key_package1: frost::keys::KeyPackage = shares[&amp;amp;signer1_id].clone().try_into()?;&lt;br/&gt;    let signer2_id = frost::Identifier::try_from(2 as u16)?;&lt;br/&gt;    let key_package2: frost::keys::KeyPackage = shares[&amp;amp;signer2_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    let message = b&amp;#34;BIP-64MOD: Anchor Data Proposal v1&amp;#34;;&lt;br/&gt;&lt;br/&gt;    let (nonces1, comms1) = frost::round1::commit(key_package1.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    let (nonces2, comms2) = frost::round1::commit(key_package2.signing_share(), &amp;amp;mut rng);&lt;br/&gt;&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    session_commitments.insert(signer1_id, comms1);&lt;br/&gt;    session_commitments.insert(signer2_id, comms2);&lt;br/&gt;&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments.clone(), message);&lt;br/&gt;&lt;br/&gt;    let share1 = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces1, &amp;amp;key_package1)?;&lt;br/&gt;    let share1_hex = hex::encode(share1.serialize());&lt;br/&gt;&lt;br/&gt;    let share2 = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces2, &amp;amp;key_package2)?;&lt;br/&gt;    let share2_hex = hex::encode(share2.serialize());&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Coordinator listening for Nostr events (simulated)...&amp;#34;);&lt;br/&gt;&lt;br/&gt;    process_relay_share(&amp;amp;share1_hex, 1_u16, &amp;amp;signing_package, &amp;amp;pubkey_package)?;&lt;br/&gt;    process_relay_share(&amp;amp;share2_hex, 2_u16, &amp;amp;signing_package, &amp;amp;pubkey_package)?;&lt;br/&gt;    println!(&amp;#34;All required shares processed. Coordinator would now aggregate.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Simulates a Signer producing a FROST signature share and preparing a Nostr event&lt;br/&gt;/// to be sent to a coordinator via a &amp;#34;mailbox&amp;#34; relay.&lt;br/&gt;///&lt;br/&gt;/// In a real ROAST setup, signers would generate their share and post it&lt;br/&gt;/// encrypted (e.g., using NIP-44) to a coordinator&amp;#39;s &amp;#34;mailbox&amp;#34; on a Nostr relay.&lt;br/&gt;/// This function demonstrates the creation of the signature share and the&lt;br/&gt;/// construction of a *simplified* Nostr event JSON.&lt;br/&gt;///&lt;br/&gt;/// # Arguments&lt;br/&gt;///&lt;br/&gt;/// * `_identifier` - The FROST identifier of the signer. (Currently unused in this specific function body).&lt;br/&gt;/// * `signing_package` - The FROST signing package received from the coordinator.&lt;br/&gt;/// * `nonces` - The signer&amp;#39;s nonces generated in Round 1.&lt;br/&gt;/// * `key_package` - The signer&amp;#39;s FROST key package.&lt;br/&gt;/// * `coordinator_pubkey` - The hex-encoded public key of the ROAST coordinator,&lt;br/&gt;///                          used to tag the Nostr event.&lt;br/&gt;///&lt;br/&gt;/// # Returns&lt;br/&gt;///&lt;br/&gt;/// A `Result` containing the JSON string of the Nostr event if successful,&lt;br/&gt;/// or a `Box&amp;lt;dyn std::error::Error&amp;gt;` if an error occurs.&lt;br/&gt;pub fn create_signer_event(&lt;br/&gt;    _identifier: frost::Identifier,&lt;br/&gt;    signing_package: &amp;amp;frost::SigningPackage,&lt;br/&gt;    nonces: &amp;amp;frost::round1::SigningNonces,&lt;br/&gt;    key_package: &amp;amp;frost::keys::KeyPackage,&lt;br/&gt;    coordinator_pubkey: &amp;amp;str, // The Hex pubkey of the ROAST coordinator&lt;br/&gt;) -&amp;gt; Result&amp;lt;String, Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;&lt;br/&gt;    // 1. Generate the partial signature share (Round 2 of FROST)&lt;br/&gt;    // This share is the core cryptographic output from the signer.&lt;br/&gt;    let share = frost::round2::sign(signing_package, nonces, key_package)?;&lt;br/&gt;    let share_bytes = share.serialize();&lt;br/&gt;    let share_hex = hex::encode(share_bytes);&lt;br/&gt;&lt;br/&gt;    // 2. Create a Session ID to tag the event&lt;br/&gt;    // This ID is derived from the signing package hash, allowing the coordinator&lt;br/&gt;    // to correlate shares belonging to the same signing session.&lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(signing_package.serialize()?);&lt;br/&gt;    let session_id = hex::encode(hasher.finalize());&lt;br/&gt;&lt;br/&gt;    // 3. Construct the Nostr Event JSON (Simplified)&lt;br/&gt;    // This JSON represents the event that a signer would post to a relay.&lt;br/&gt;    // In a production ROAST system, the &amp;#39;content&amp;#39; field (the signature share)&lt;br/&gt;    // would be encrypted for the coordinator using NIP-44.&lt;br/&gt;    let event = serde_json::json!({&lt;br/&gt;        &amp;#34;kind&amp;#34;: 4, // Example: Using Kind 4 (Private Message), though custom Kinds could be used for Sovereign Stack.&lt;br/&gt;        &amp;#34;pubkey&amp;#34;: hex::encode(key_package.verifying_key().serialize()?.as_slice()), // Signer&amp;#39;s public key&lt;br/&gt;        &amp;#34;created_at&amp;#34;: 1712050000, // Example timestamp&lt;br/&gt;        &amp;#34;tags&amp;#34;: [&lt;br/&gt;            [&amp;#34;p&amp;#34;, coordinator_pubkey],       // &amp;#39;p&amp;#39; tag: Directs the event to the coordinator.&lt;br/&gt;            [&amp;#34;i&amp;#34;, session_id],               // &amp;#39;i&amp;#39; tag: Provides a session identifier for filtering/requests.&lt;br/&gt;            [&amp;#34;t&amp;#34;, &amp;#34;frost-signature-share&amp;#34;]   // &amp;#39;t&amp;#39; tag: A searchable label for the event type.&lt;br/&gt;        ],&lt;br/&gt;        &amp;#34;content&amp;#34;: share_hex, // The actual signature share (would be encrypted in production).&lt;br/&gt;        &amp;#34;id&amp;#34;: &amp;#34;...&amp;#34;, // Event ID (filled by relay upon publishing)&lt;br/&gt;        &amp;#34;sig&amp;#34;: &amp;#34;...&amp;#34; // Event signature (filled by relay upon publishing)&lt;br/&gt;    });&lt;br/&gt;&lt;br/&gt;    Ok(event.to_string())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;pub fn simulate_frost_mailbox_post_signer() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    use rand::thread_rng;&lt;br/&gt;    use std::collections::BTreeMap;&lt;br/&gt;    use frost_secp256k1_tr as frost;&lt;br/&gt;&lt;br/&gt;    // This example simulates a single signer&amp;#39;s role in a ROAST mailbox post workflow.&lt;br/&gt;    // The general workflow is:&lt;br/&gt;    // 1. Coordinator sends a request for signatures (e.g., on a BIP-64MOD proposal).&lt;br/&gt;    // 2. Signers receive the proposal, perform local verification.&lt;br/&gt;    // 3. Each signer generates their signature share and posts it (encrypted) to a&lt;br/&gt;    //    Nostr relay, targeting the coordinator&amp;#39;s mailbox.&lt;br/&gt;    // 4. The coordinator collects enough shares to aggregate the final signature.&lt;br/&gt;&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    // For this example, we simulate a 2-of-2 threshold for simplicity.&lt;br/&gt;    let (max_signers, min_signers) = (2, 2);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 1. Key Generation (Simulated Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // In a real distributed setup, this would be DKG. Here, a &amp;#34;trusted dealer&amp;#34;&lt;br/&gt;    // generates the shares and public key package.&lt;br/&gt;    let (shares, _pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // For a 2-of-2 scheme, we have two signers. Let&amp;#39;s pick signer 1.&lt;br/&gt;    let signer1_id = frost::Identifier::try_from(1 as u16)?;&lt;br/&gt;    let key_package1: frost::keys::KeyPackage = shares[&amp;amp;signer1_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    let signer2_id = frost::Identifier::try_from(2 as u16)?;&lt;br/&gt;    let key_package2: frost::keys::KeyPackage = shares[&amp;amp;signer2_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    // The message that is to be signed (e.g., a hash of a Git commit or a Nostr event ID).&lt;br/&gt;    let message = b&amp;#34;This is a test message for ROAST mailbox post.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 2. Round 1: Commitment Phase (Signer&amp;#39;s role)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Each signer generates nonces and commitments.&lt;br/&gt;    let (nonces1, comms1) = frost::round1::commit(key_package1.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    let (nonces2, comms2) = frost::round1::commit(key_package2.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    &lt;br/&gt;    // The coordinator collects these commitments. Here, we simulate by putting them in a BTreeMap.&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    session_commitments.insert(signer1_id, comms1);&lt;br/&gt;    session_commitments.insert(signer2_id, comms2);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 3. Signing Package Creation (Coordinator&amp;#39;s role, simulated for context)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // The coordinator combines the collected commitments and the message to be signed&lt;br/&gt;    // into a signing package, which is then sent back to the signers.&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments, message);&lt;br/&gt;&lt;br/&gt;    // Dummy coordinator public key. In a real scenario, this would be the&lt;br/&gt;    // actual public key of the ROAST coordinator, used for event tagging&lt;br/&gt;    // and encryption (NIP-44).&lt;br/&gt;    let coordinator_pubkey_hex = &amp;#34;0000000000000000000000000000000000000000000000000000000000000001&amp;#34;;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 4. Create the Signer Event (Signer&amp;#39;s role)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // We demonstrate for signer 1. Signer 2 would perform a similar action.&lt;br/&gt;    let event_json_signer1 = create_signer_event(&lt;br/&gt;        signer1_id,&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;nonces1,&lt;br/&gt;        &amp;amp;key_package1,&lt;br/&gt;        coordinator_pubkey_hex,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Generated Nostr Event for Signer 1 Mailbox Post:&lt;br/&gt;{}&amp;#34;, event_json_signer1);&lt;br/&gt;&lt;br/&gt;    // Similarly, Signer 2 would generate their event:&lt;br/&gt;    let event_json_signer2 = create_signer_event(&lt;br/&gt;        signer2_id,&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;nonces2,&lt;br/&gt;        &amp;amp;key_package2,&lt;br/&gt;        coordinator_pubkey_hex,&lt;br/&gt;    )?;&lt;br/&gt;    println!(&amp;#34;Generated Nostr Event for Signer 2 Mailbox Post:&lt;br/&gt;{}&amp;#34;, event_json_signer2);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}
    </content>
    <updated>2026-04-04T01:41:55Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsqwq937kwgzmdckcwscmz2kjps8q29kduunu0h5tacf5sq9ngqqagzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjcdttp9</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsqwq937kwgzmdckcwscmz2kjps8q29kduunu0h5tacf5sq9ngqqagzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjcdttp9" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_repository_state;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let branch_name = &amp;#34;main&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Publishing repository state...&amp;#34;);&lt;br/&gt;    publish_repository_state!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        branch_name,&lt;br/&gt;        commit_id&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository state published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_repository_state --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:49Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqspld4zt6n6w9cuuhp8ss8f9k0pfuljk3rr5zuqrrq2uudhtpx06yszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj434l2r</id>
    
      <title type="html">&amp;lt;?xml version=&amp;#39;1.0&amp;#39; ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqspld4zt6n6w9cuuhp8ss8f9k0pfuljk3rr5zuqrrq2uudhtpx06yszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj434l2r" />
    <content type="html">
      &amp;lt;?xml version=&amp;#39;1.0&amp;#39; encoding=&amp;#39;windows-1252&amp;#39;?&amp;gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  Copyright (C) 2017 Christopher R. Field.&lt;br/&gt;&lt;br/&gt;  Licensed under the Apache License, Version 2.0 (the &amp;#34;License&amp;#34;);&lt;br/&gt;  you may not use this file except in compliance with the License.&lt;br/&gt;  You may obtain a copy of the License at&lt;br/&gt;&lt;br/&gt;  &lt;a href=&#34;http://www.apache.org/licenses/LICENSE-2.0&#34;&gt;http://www.apache.org/licenses/LICENSE-2.0&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;  Unless required by applicable law or agreed to in writing, software&lt;br/&gt;  distributed under the License is distributed on an &amp;#34;AS IS&amp;#34; BASIS,&lt;br/&gt;  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;br/&gt;  See the License for the specific language governing permissions and&lt;br/&gt;  limitations under the License.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  The &amp;#34;cargo wix&amp;#34; subcommand provides a variety of predefined variables available&lt;br/&gt;  for customization of this template. The values for each variable are set at&lt;br/&gt;  installer creation time. The following variables are available:&lt;br/&gt;&lt;br/&gt;  TargetTriple      = The rustc target triple name.&lt;br/&gt;  TargetEnv         = The rustc target environment. This is typically either&lt;br/&gt;                      &amp;#34;msvc&amp;#34; or &amp;#34;gnu&amp;#34; depending on the toolchain downloaded and&lt;br/&gt;                      installed.&lt;br/&gt;  TargetVendor      = The rustc target vendor. This is typically &amp;#34;pc&amp;#34;, but Rust&lt;br/&gt;                      does support other vendors, like &amp;#34;uwp&amp;#34;.&lt;br/&gt;  CargoTargetBinDir = The complete path to the directory containing the&lt;br/&gt;                      binaries (exes) to include. The default would be&lt;br/&gt;                      &amp;#34;target\release\&amp;#34;. If an explicit rustc target triple is&lt;br/&gt;                      used, i.e. cross-compiling, then the default path would&lt;br/&gt;                      be &amp;#34;target\&amp;lt;CARGO_TARGET&amp;gt;\&amp;lt;CARGO_PROFILE&amp;gt;&amp;#34;,&lt;br/&gt;                      where &amp;#34;&amp;lt;CARGO_TARGET&amp;gt;&amp;#34; is replaced with the &amp;#34;CargoTarget&amp;#34;&lt;br/&gt;                      variable value and &amp;#34;&amp;lt;CARGO_PROFILE&amp;gt;&amp;#34; is replaced with the&lt;br/&gt;                      value from the &amp;#34;CargoProfile&amp;#34; variable. This can also&lt;br/&gt;                      be overridden manually with the &amp;#34;target-bin-dir&amp;#34; flag.&lt;br/&gt;  CargoTargetDir    = The path to the directory for the build artifacts, i.e.&lt;br/&gt;                      &amp;#34;target&amp;#34;.&lt;br/&gt;  CargoProfile      = The cargo profile used to build the binaries&lt;br/&gt;                      (usually &amp;#34;debug&amp;#34; or &amp;#34;release&amp;#34;).&lt;br/&gt;  Version           = The version for the installer. The default is the&lt;br/&gt;                      &amp;#34;Major.Minor.Fix&amp;#34; semantic versioning number of the Rust&lt;br/&gt;                      package.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  Please do not remove these pre-processor If-Else blocks. These are used with&lt;br/&gt;  the `cargo wix` subcommand to automatically determine the installation&lt;br/&gt;  destination for 32-bit versus 64-bit installers. Removal of these lines will&lt;br/&gt;  cause installation errors.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&amp;lt;?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64 ?&amp;gt;&lt;br/&gt;    &amp;lt;?define PlatformProgramFilesFolder = &amp;#34;ProgramFiles64Folder&amp;#34; ?&amp;gt;&lt;br/&gt;&amp;lt;?else ?&amp;gt;&lt;br/&gt;    &amp;lt;?define PlatformProgramFilesFolder = &amp;#34;ProgramFilesFolder&amp;#34; ?&amp;gt;&lt;br/&gt;&amp;lt;?endif ?&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;Wix xmlns=&amp;#39;&lt;a href=&#34;http://schemas.microsoft.com/wix/2006/wi&amp;#39;&amp;gt&#34;&gt;http://schemas.microsoft.com/wix/2006/wi&amp;#39;&amp;gt&lt;/a&gt;;&lt;br/&gt;&lt;br/&gt;    &amp;lt;Product&lt;br/&gt;        Id=&amp;#39;*&amp;#39;&lt;br/&gt;        Name=&amp;#39;get_file_hash&amp;#39;&lt;br/&gt;        UpgradeCode=&amp;#39;DED69220-26E3-4406-B564-7F2B58C56F57&amp;#39;&lt;br/&gt;        Manufacturer=&amp;#39;gnostr admin@gnostr.org&amp;#39;&lt;br/&gt;        Language=&amp;#39;1033&amp;#39;&lt;br/&gt;        Codepage=&amp;#39;1252&amp;#39;&lt;br/&gt;        Version=&amp;#39;$(var.Version)&amp;#39;&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Package Id=&amp;#39;*&amp;#39;&lt;br/&gt;            Keywords=&amp;#39;Installer&amp;#39;&lt;br/&gt;            Description=&amp;#39;A utility crate providing a procedural macro to compute and embed file hashes at compile time.&amp;#39;&lt;br/&gt;            Manufacturer=&amp;#39;gnostr admin@gnostr.org&amp;#39;&lt;br/&gt;            InstallerVersion=&amp;#39;450&amp;#39;&lt;br/&gt;            Languages=&amp;#39;1033&amp;#39;&lt;br/&gt;            Compressed=&amp;#39;yes&amp;#39;&lt;br/&gt;            InstallScope=&amp;#39;perMachine&amp;#39;&lt;br/&gt;            SummaryCodepage=&amp;#39;1252&amp;#39;&lt;br/&gt;            /&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;MajorUpgrade&lt;br/&gt;            Schedule=&amp;#39;afterInstallInitialize&amp;#39;&lt;br/&gt;            DowngradeErrorMessage=&amp;#39;A newer version of [ProductName] is already installed. Setup will now exit.&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Media Id=&amp;#39;1&amp;#39; Cabinet=&amp;#39;media1.cab&amp;#39; EmbedCab=&amp;#39;yes&amp;#39; DiskPrompt=&amp;#39;CD-ROM #1&amp;#39;/&amp;gt;&lt;br/&gt;        &amp;lt;Property Id=&amp;#39;DiskPrompt&amp;#39; Value=&amp;#39;get_file_hash Installation&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Directory Id=&amp;#39;TARGETDIR&amp;#39; Name=&amp;#39;SourceDir&amp;#39;&amp;gt;&lt;br/&gt;            &amp;lt;Directory Id=&amp;#39;$(var.PlatformProgramFilesFolder)&amp;#39; Name=&amp;#39;PFiles&amp;#39;&amp;gt;&lt;br/&gt;                &amp;lt;Directory Id=&amp;#39;APPLICATIONFOLDER&amp;#39; Name=&amp;#39;get_file_hash&amp;#39;&amp;gt;&lt;br/&gt;                    &lt;br/&gt;                    &amp;lt;!--&lt;br/&gt;                      Enabling the license sidecar file in the installer is a four step process:&lt;br/&gt;&lt;br/&gt;                      1. Uncomment the `Component` tag and its contents.&lt;br/&gt;                      2. Change the value for the `Source` attribute in the `File` tag to a path&lt;br/&gt;                         to the file that should be included as the license sidecar file. The path&lt;br/&gt;                         can, and probably should be, relative to this file.&lt;br/&gt;                      3. Change the value for the `Name` attribute in the `File` tag to the&lt;br/&gt;                         desired name for the file when it is installed alongside the `bin` folder&lt;br/&gt;                         in the installation directory. This can be omitted if the desired name is&lt;br/&gt;                         the same as the file name.&lt;br/&gt;                      4. Uncomment the `ComponentRef` tag with the Id attribute value of &amp;#34;License&amp;#34;&lt;br/&gt;                         further down in this file.&lt;br/&gt;                    --&amp;gt;&lt;br/&gt;                    &amp;lt;!--&lt;br/&gt;                    &amp;lt;Component Id=&amp;#39;License&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                        &amp;lt;File Id=&amp;#39;LicenseFile&amp;#39; Name=&amp;#39;ChangeMe&amp;#39; DiskId=&amp;#39;1&amp;#39; Source=&amp;#39;C:\Path\To\File&amp;#39; KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                    &amp;lt;/Component&amp;gt;&lt;br/&gt;                    --&amp;gt;&lt;br/&gt;&lt;br/&gt;                    &amp;lt;Directory Id=&amp;#39;Bin&amp;#39; Name=&amp;#39;bin&amp;#39;&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;Path&amp;#39; Guid=&amp;#39;8DB39A25-8B99-4C25-8CF5-4704353C7C6E&amp;#39; KeyPath=&amp;#39;yes&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;Environment&lt;br/&gt;                                Id=&amp;#39;PATH&amp;#39;&lt;br/&gt;                                Name=&amp;#39;PATH&amp;#39;&lt;br/&gt;                                Value=&amp;#39;[Bin]&amp;#39;&lt;br/&gt;                                Permanent=&amp;#39;no&amp;#39;&lt;br/&gt;                                Part=&amp;#39;last&amp;#39;&lt;br/&gt;                                Action=&amp;#39;set&amp;#39;&lt;br/&gt;                                System=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;binary0&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;File&lt;br/&gt;                                Id=&amp;#39;exe0&amp;#39;&lt;br/&gt;                                Name=&amp;#39;get_file_hash.exe&amp;#39;&lt;br/&gt;                                DiskId=&amp;#39;1&amp;#39;&lt;br/&gt;                                Source=&amp;#39;$(var.CargoTargetBinDir)\get_file_hash.exe&amp;#39;&lt;br/&gt;                                KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;binary1&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;File&lt;br/&gt;                                Id=&amp;#39;exe1&amp;#39;&lt;br/&gt;                                Name=&amp;#39;readme.exe&amp;#39;&lt;br/&gt;                                DiskId=&amp;#39;1&amp;#39;&lt;br/&gt;                                Source=&amp;#39;$(var.CargoTargetBinDir)\readme.exe&amp;#39;&lt;br/&gt;                                KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                    &amp;lt;/Directory&amp;gt;&lt;br/&gt;                &amp;lt;/Directory&amp;gt;&lt;br/&gt;            &amp;lt;/Directory&amp;gt;&lt;br/&gt;        &amp;lt;/Directory&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Feature&lt;br/&gt;            Id=&amp;#39;Binaries&amp;#39;&lt;br/&gt;            Title=&amp;#39;Application&amp;#39;&lt;br/&gt;            Description=&amp;#39;Installs all binaries and the license.&amp;#39;&lt;br/&gt;            Level=&amp;#39;1&amp;#39;&lt;br/&gt;            ConfigurableDirectory=&amp;#39;APPLICATIONFOLDER&amp;#39;&lt;br/&gt;            AllowAdvertise=&amp;#39;no&amp;#39;&lt;br/&gt;            Display=&amp;#39;expand&amp;#39;&lt;br/&gt;            Absent=&amp;#39;disallow&amp;#39;&amp;gt;&lt;br/&gt;            &lt;br/&gt;            &amp;lt;!--&lt;br/&gt;              Uncomment the following `ComponentRef` tag to add the license&lt;br/&gt;              sidecar file to the installer.&lt;br/&gt;            --&amp;gt;&lt;br/&gt;            &amp;lt;!--&amp;lt;ComponentRef Id=&amp;#39;License&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;            &amp;lt;ComponentRef Id=&amp;#39;binary0&amp;#39;/&amp;gt;&lt;br/&gt;            &amp;lt;ComponentRef Id=&amp;#39;binary1&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;            &amp;lt;Feature&lt;br/&gt;                Id=&amp;#39;Environment&amp;#39;&lt;br/&gt;                Title=&amp;#39;PATH Environment Variable&amp;#39;&lt;br/&gt;                Description=&amp;#39;Add the install location of the [ProductName] executable to the PATH system environment variable. This allows the [ProductName] executable to be called from any location.&amp;#39;&lt;br/&gt;                Level=&amp;#39;1&amp;#39;&lt;br/&gt;                Absent=&amp;#39;allow&amp;#39;&amp;gt;&lt;br/&gt;                &amp;lt;ComponentRef Id=&amp;#39;Path&amp;#39;/&amp;gt;&lt;br/&gt;            &amp;lt;/Feature&amp;gt;&lt;br/&gt;        &amp;lt;/Feature&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;SetProperty Id=&amp;#39;ARPINSTALLLOCATION&amp;#39; Value=&amp;#39;[APPLICATIONFOLDER]&amp;#39; After=&amp;#39;CostFinalize&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the following `Icon` and `Property` tags to change the product icon.&lt;br/&gt;&lt;br/&gt;          The product icon is the graphic that appears in the Add/Remove&lt;br/&gt;          Programs control panel for the application.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;Icon Id=&amp;#39;ProductICO&amp;#39; SourceFile=&amp;#39;wix\Product.ico&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;Property Id=&amp;#39;ARPPRODUCTICON&amp;#39; Value=&amp;#39;ProductICO&amp;#39; /&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Property Id=&amp;#39;ARPHELPLINK&amp;#39; Value=&amp;#39;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash&amp;#39;/&amp;gt&#34;&gt;https://github.com/gnostr-org/get_file_hash&amp;#39;/&amp;gt&lt;/a&gt;;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;UI&amp;gt;&lt;br/&gt;            &amp;lt;UIRef Id=&amp;#39;WixUI_FeatureTree&amp;#39;/&amp;gt;&lt;br/&gt;            &lt;br/&gt;            &amp;lt;!--&lt;br/&gt;              Enabling the EULA dialog in the installer is a three step process:&lt;br/&gt;&lt;br/&gt;                1. Comment out or remove the two `Publish` tags that follow the&lt;br/&gt;                   `WixVariable` tag.&lt;br/&gt;                2. Uncomment the `&amp;lt;WixVariable Id=&amp;#39;WixUILicenseRtf&amp;#39; Value=&amp;#39;Path\to\Eula.rft&amp;#39;&amp;gt;` tag further down&lt;br/&gt;                3. Replace the `Value` attribute of the `WixVariable` tag with&lt;br/&gt;                   the path to a RTF file that will be used as the EULA and&lt;br/&gt;                   displayed in the license agreement dialog.&lt;br/&gt;            --&amp;gt;&lt;br/&gt;            &amp;lt;Publish Dialog=&amp;#39;WelcomeDlg&amp;#39; Control=&amp;#39;Next&amp;#39; Event=&amp;#39;NewDialog&amp;#39; Value=&amp;#39;CustomizeDlg&amp;#39; Order=&amp;#39;99&amp;#39;&amp;gt;1&amp;lt;/Publish&amp;gt;&lt;br/&gt;            &amp;lt;Publish Dialog=&amp;#39;CustomizeDlg&amp;#39; Control=&amp;#39;Back&amp;#39; Event=&amp;#39;NewDialog&amp;#39; Value=&amp;#39;WelcomeDlg&amp;#39; Order=&amp;#39;99&amp;#39;&amp;gt;1&amp;lt;/Publish&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;/UI&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Enabling the EULA dialog in the installer requires uncommenting&lt;br/&gt;          the following `WixUILicenseRTF` tag and changing the `Value`&lt;br/&gt;          attribute.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!-- &amp;lt;WixVariable Id=&amp;#39;WixUILicenseRtf&amp;#39; Value=&amp;#39;Relative\Path\to\Eula.rtf&amp;#39;/&amp;gt; --&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the next `WixVariable` tag to customize the installer&amp;#39;s&lt;br/&gt;          Graphical User Interface (GUI) and add a custom banner image across&lt;br/&gt;          the top of each screen. See the WiX Toolset documentation for details&lt;br/&gt;          about customization.&lt;br/&gt;&lt;br/&gt;          The banner BMP dimensions are 493 x 58 pixels.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;WixVariable Id=&amp;#39;WixUIBannerBmp&amp;#39; Value=&amp;#39;wix\Banner.bmp&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the next `WixVariable` tag to customize the installer&amp;#39;s&lt;br/&gt;          Graphical User Interface (GUI) and add a custom image to the first&lt;br/&gt;          dialog, or screen. See the WiX Toolset documentation for details about&lt;br/&gt;          customization.&lt;br/&gt;&lt;br/&gt;          The dialog BMP dimensions are 493 x 312 pixels.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;WixVariable Id=&amp;#39;WixUIDialogBmp&amp;#39; Value=&amp;#39;wix\Dialog.bmp&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;    &amp;lt;/Product&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;/Wix&amp;gt;&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:48Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsf8qrffp4tflkgxd4h0efyscc8fuzwldcq02uz4xeskhne80vg9dszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj00aksj</id>
    
      <title type="html"># `get_file_hash` macro This project provides a Rust procedural ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsf8qrffp4tflkgxd4h0efyscc8fuzwldcq02uz4xeskhne80vg9dszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj00aksj" />
    <content type="html">
      # `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use get_file_hash::CARGO_TOML_HASH;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let readme_hash = get_file_hash!(&amp;#34;src/bin/readme.rs&amp;#34;);&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, lib_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/bin/readme.rs is: {}&amp;#34;, readme_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of Cargo.toml is: {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## Release&lt;br/&gt;## [`README.md`](./README.md)&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin readme &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## [`src/bin/readme.rs`](src/bin/readme.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/readme.rs`&lt;br/&gt;## NIP-34 Integration: Git Repository Events on Nostr&lt;br/&gt;&lt;br/&gt;This library provides a set of powerful macros and functions for integrating Git repository events with the Nostr protocol, adhering to the [NIP-34: Git Repositories on Nostr](&lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/34.md&#34;&gt;https://github.com/nostr-protocol/nips/blob/master/34.md&lt;/a&gt;) specification.&lt;br/&gt;&lt;br/&gt;These tools allow you to publish various Git-related events to Nostr relays, enabling decentralized tracking and collaboration for your code repositories.&lt;br/&gt;&lt;br/&gt;### Available NIP-34 Macros&lt;br/&gt;&lt;br/&gt;Each macro provides a convenient way to publish specific NIP-34 event kinds:&lt;br/&gt;&lt;br/&gt;*   [`repository_announcement!`](#repository_announcement)&lt;br/&gt;    *   Publishes a `Repository Announcement` event (Kind 30617) to announce a new or updated Git repository.&lt;br/&gt;*   [`publish_patch!`](#publish_patch)&lt;br/&gt;    *   Publishes a `Patch` event (Kind 1617) containing a Git patch (diff) for a specific commit.&lt;br/&gt;*   [`publish_pull_request!`](#publish_pull_request)&lt;br/&gt;    *   Publishes a `Pull Request` event (Kind 1618) to propose changes and facilitate code review.&lt;br/&gt;*   [`publish_pr_update!`](#publish_pr_update)&lt;br/&gt;    *   Publishes a `Pull Request Update` event (Kind 1619) to update an existing pull request.&lt;br/&gt;*   [`publish_repository_state!`](#publish_repository_state)&lt;br/&gt;    *   Publishes a `Repository State` event (Kind 1620) to announce the current state of a branch (e.g., its latest commit).&lt;br/&gt;*   [`publish_issue!`](#publish_issue)&lt;br/&gt;    *   Publishes an `Issue` event (Kind 1621) to report bugs, request features, or track tasks.&lt;br/&gt;&lt;br/&gt;### Running NIP-34 Examples&lt;br/&gt;&lt;br/&gt;To see these macros in action, navigate to the `examples/` directory and run each example individually with the `nostr` feature enabled:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --example repository_announcement --features nostr&lt;br/&gt;cargo run --example publish_patch --features nostr&lt;br/&gt;cargo run --example publish_pull_request --features nostr&lt;br/&gt;cargo run --example publish_pr_update --features nostr&lt;br/&gt;cargo run --example publish_repository_state --features nostr&lt;br/&gt;cargo run --example publish_issue --features nostr&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;*   **SHA-256 Hash:** 6c6325c5a4c14f44cbda6ca53179ab3d6666ce7c916365668c6dd1d79215db59&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`build.rs`](build.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `build.rs`&lt;br/&gt;*   **SHA-256 Hash:** 20c958c8cbb5c77cf5eb3763b6da149b61241d328df52d39b7aa97903305c889&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`Cargo.toml`](Cargo.toml)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `Cargo.toml`&lt;br/&gt;*   **SHA-256 Hash:** e3f392bf23b5fb40902acd313a8c76d1943060b6805ea8615de62f9baf0c6513&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`src/lib.rs`](src/lib.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/lib.rs`&lt;br/&gt;*   **SHA-256 Hash:** 591593482a6c9aac8793aa1e488e613f52a4effb1ec3465fd9d6a54537f2b123&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:46Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs0ze8kz9tjszz0vwz6w5s7hpcxczvr8mrk9s8kuvdpmvqnqwa3jlczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjqpfq33</id>
    
      <title type="html">#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))] ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs0ze8kz9tjszz0vwz6w5s7hpcxczvr8mrk9s8kuvdpmvqnqwa3jlczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjqpfq33" />
    <content type="html">
      #[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use std::fs;&lt;br/&gt;    use std::path::PathBuf;&lt;br/&gt;&lt;br/&gt;    let manifest_dir = PathBuf::from(std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap());&lt;br/&gt;    let crate_src_path = manifest_dir.join(&amp;#34;src&amp;#34;).join(&amp;#34;online_relays_gps.csv&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Only download if the file doesn&amp;#39;t exist or is empty&lt;br/&gt;    if !crate_src_path.exists() || fs::metadata(&amp;amp;crate_src_path).map(|m| m.len() == 0).unwrap_or(true) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Downloading online_relays_gps.csv...&amp;#34;);&lt;br/&gt;        let url = &amp;#34;&lt;a href=&#34;https://raw.githubusercontent.com/permissionlesstech/bitchat/main/relays/online_relays_gps.csv&amp;#34&#34;&gt;https://raw.githubusercontent.com/permissionlesstech/bitchat/main/relays/online_relays_gps.csv&amp;#34&lt;/a&gt;;;&lt;br/&gt;        match reqwest::get(url).await {&lt;br/&gt;            Ok(response) =&amp;gt; {&lt;br/&gt;                if response.status().is_success() {&lt;br/&gt;                    match response.text().await {&lt;br/&gt;                        Ok(content) =&amp;gt; {&lt;br/&gt;                            fs::write(&amp;amp;crate_src_path, content).expect(&amp;#34;Unable to write online_relays_gps.csv&amp;#34;);&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Successfully downloaded online_relays_gps.csv to {:?}&amp;#34;, crate_src_path);&lt;br/&gt;                        },&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to get text from response: {}&amp;#34;, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                } else {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to download online_relays_gps.csv: HTTP status {}&amp;#34;, response.status());&lt;br/&gt;                }&lt;br/&gt;            },&lt;br/&gt;            Err(e) =&amp;gt; {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to fetch online_relays_gps.csv: {}&amp;#34;, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;)))]&lt;br/&gt;fn main() {&lt;br/&gt;    // Placeholder for when the nostr feature is not enabled or in debug mode&lt;br/&gt;    println!(&amp;#34;cargo:warning=Skipping online_relays_gps.csv download (nostr feature not enabled or debug mode)&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:37Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqswekt4j0y9kkw68up7ufpqzhggtejljy8t07dn038z3mnxuqcjp6qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj92nns8</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqswekt4j0y9kkw68up7ufpqzhggtejljy8t07dn038z3mnxuqcjp6qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj92nns8" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_pull_request;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;0123456789abcdef0123456789abcdef01234567&amp;#34;;&lt;br/&gt;    let clone_url = &amp;#34;git@github.com:user/my-feature-branch.git&amp;#34;;&lt;br/&gt;    let title = Some(&amp;#34;Feat: Add new awesome feature example&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without title and build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request without title and build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request without title and build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With title but without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request with title but without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        title&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with title but without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 3: With build_manifest_event_id but without title&lt;br/&gt;    println!(&amp;#34;Publishing pull request with build_manifest_event_id but without title...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        None, // Explicitly pass None for title&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with build_manifest_event_id but without title published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 4: With title and build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request with title and build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        title,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with title and build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_pull_request --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:36Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsvnjkdpqvh23dht52g0r39dem2ttgpckkpf9decwpkhffq5hwa9hszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjqdd8em</id>
    
      <title type="html">use std::process::Command; use std::fs; use sha2::{Digest, ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsvnjkdpqvh23dht52g0r39dem2ttgpckkpf9decwpkhffq5hwa9hszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjqdd8em" />
    <content type="html">
      use std::process::Command;&lt;br/&gt;use std::fs;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn calculate_sha256(file_path: &amp;amp;str) -&amp;gt; String {&lt;br/&gt;    let content = fs::read(file_path).expect(&amp;#34;Unable to read file&amp;#34;);&lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(&amp;amp;content);&lt;br/&gt;    hasher.finalize()&lt;br/&gt;        .iter()&lt;br/&gt;        .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;        .collect()&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[test]&lt;br/&gt;fn test_get_file_hash_binary_no_features() {&lt;br/&gt;    let output = Command::new(&amp;#34;cargo&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;run&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--bin&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;get_file_hash&amp;#34;)&lt;br/&gt;        .output()&lt;br/&gt;        .expect(&amp;#34;Failed to execute command&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let stdout = String::from_utf8_lossy(&amp;amp;output.stdout);&lt;br/&gt;    let stderr = String::from_utf8_lossy(&amp;amp;output.stderr);&lt;br/&gt;&lt;br/&gt;    // Assert that the command ran successfully&lt;br/&gt;    assert!(output.status.success(), &amp;#34;Command failed with stderr: {}&amp;#34;, stderr);&lt;br/&gt;&lt;br/&gt;    // Manually calculate the hash of the binary&amp;#39;s source file&lt;br/&gt;    let expected_hash = calculate_sha256(&amp;#34;src/bin/get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains the correct hash&lt;br/&gt;    // Check for the raw hash first&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash), &amp;#34;Output did not contain raw expected hash. Expected: {}, Actual: {}&amp;#34;, expected_hash, stdout);&lt;br/&gt;&lt;br/&gt;    // Then check for the formatted string, including backticks&lt;br/&gt;    // Use a regex-like check for more flexibility with newlines if needed, or refine to exact match&lt;br/&gt;    let expected_hash_line = format!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, expected_hash);&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash_line), &amp;#34;Output did not contain expected hash line. Expected line: {}, Actual: {}&amp;#34;, expected_hash_line, stdout);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    assert!(stdout.contains(&amp;#34;Integrity Verified.&amp;#34;), &amp;#34;Output did not contain &amp;#39;Integrity Verified.&amp;#39;. stdout: {}&amp;#34;, stdout);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Output from get_file_hash binary (no features):&lt;br/&gt;{}&amp;#34;, stdout);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[test]&lt;br/&gt;fn test_get_file_hash_binary_with_nostr_feature() {&lt;br/&gt;    let output = Command::new(&amp;#34;cargo&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;run&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--bin&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;get_file_hash&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--features&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;nostr&amp;#34;)&lt;br/&gt;        .output()&lt;br/&gt;        .expect(&amp;#34;Failed to execute command&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let stdout = String::from_utf8_lossy(&amp;amp;output.stdout);&lt;br/&gt;    let stderr = String::from_utf8_lossy(&amp;amp;output.stderr);&lt;br/&gt;&lt;br/&gt;    // Assert that the command ran successfully&lt;br/&gt;    assert!(output.status.success(), &amp;#34;Command failed with stderr: {}&amp;#34;, stderr);&lt;br/&gt;&lt;br/&gt;    // Manually calculate the hash of the binary&amp;#39;s source file&lt;br/&gt;    let expected_hash = calculate_sha256(&amp;#34;src/bin/get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains the correct hash&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash), &amp;#34;Output did not contain raw expected hash. Expected: {}, Actual: {}&amp;#34;, expected_hash, stdout);&lt;br/&gt;&lt;br/&gt;    // Then check for the formatted string, including backticks&lt;br/&gt;    let expected_hash_line = format!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, expected_hash);&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash_line), &amp;#34;Output did not contain expected hash line. Expected line: {}, Actual: {}&amp;#34;, expected_hash_line, stdout);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    assert!(stdout.contains(&amp;#34;Integrity Verified.&amp;#34;), &amp;#34;Output did not contain &amp;#39;Integrity Verified.&amp;#39;. stdout: {}&amp;#34;, stdout);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Output from get_file_hash binary (with nostr feature):&lt;br/&gt;{}&amp;#34;, stdout);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:36Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs8p9pj7af6nfvugntzm57kv8g7hm9tzw7hh3q538yc07cjyxwtctszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj2zjp9z</id>
    
      <title type="html">[workspace] members = [&amp;#34;.&amp;#34;, ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs8p9pj7af6nfvugntzm57kv8g7hm9tzw7hh3q538yc07cjyxwtctszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj2zjp9z" />
    <content type="html">
      [workspace]&lt;br/&gt;members = [&amp;#34;.&amp;#34;, &amp;#34;src/get_file_hash_core&amp;#34;]&lt;br/&gt;&lt;br/&gt;[workspace.package]&lt;br/&gt;version = &amp;#34;0.3.3&amp;#34;&lt;br/&gt;edition = &amp;#34;2024&amp;#34;&lt;br/&gt;license = &amp;#34;MIT&amp;#34;&lt;br/&gt;authors = [&amp;#34;gnostr admin@gnostr.org&amp;#34;]&lt;br/&gt;documentation = &amp;#34;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash#readme&amp;#34&#34;&gt;https://github.com/gnostr-org/get_file_hash#readme&amp;#34&lt;/a&gt;;&lt;br/&gt;homepage = &amp;#34;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash&amp;#34&#34;&gt;https://github.com/gnostr-org/get_file_hash&amp;#34&lt;/a&gt;;&lt;br/&gt;repository = &amp;#34;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash&amp;#34&#34;&gt;https://github.com/gnostr-org/get_file_hash&amp;#34&lt;/a&gt;;&lt;br/&gt;description = &amp;#34;A utility crate providing a procedural macro to compute and embed file hashes at compile time.&amp;#34;&lt;br/&gt;&lt;br/&gt;[package]&lt;br/&gt;name = &amp;#34;get_file_hash&amp;#34;&lt;br/&gt;version.workspace = true&lt;br/&gt;edition.workspace = true&lt;br/&gt;description.workspace = true&lt;br/&gt;repository.workspace = true&lt;br/&gt;homepage.workspace = true&lt;br/&gt;authors.workspace = true&lt;br/&gt;license.workspace = true&lt;br/&gt;&lt;br/&gt;[package.metadata.wix]&lt;br/&gt;upgrade-guid = &amp;#34;DED69220-26E3-4406-B564-7F2B58C56F57&amp;#34;&lt;br/&gt;path-guid = &amp;#34;8DB39A25-8B99-4C25-8CF5-4704353C7C6E&amp;#34;&lt;br/&gt;license = false&lt;br/&gt;eula = false&lt;br/&gt;&lt;br/&gt;[features]&lt;br/&gt;nostr = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:hex&amp;#34;]&lt;br/&gt;frost = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:hex&amp;#34;]&lt;br/&gt;&lt;br/&gt;[workspace.dependencies]&lt;br/&gt;get_file_hash_core = { features = [&amp;#34;nostr&amp;#34;], path = &amp;#34;src/get_file_hash_core&amp;#34;, version = &amp;#34;0.3.3&amp;#34; }&lt;br/&gt;rand_chacha = &amp;#34;0.3&amp;#34;&lt;br/&gt;sha2 = &amp;#34;0.11.0&amp;#34;&lt;br/&gt;nostr = &amp;#34;0.44.2&amp;#34;&lt;br/&gt;nostr-sdk = &amp;#34;0.44.0&amp;#34;&lt;br/&gt;hex = &amp;#34;0.4.2&amp;#34;&lt;br/&gt;tokio = &amp;#34;1&amp;#34;&lt;br/&gt;serde_json = &amp;#34;1.0&amp;#34;&lt;br/&gt;csv = { version = &amp;#34;1.3.0&amp;#34;, default-features = false }&lt;br/&gt;url = &amp;#34;2.5.0&amp;#34;&lt;br/&gt;reqwest = { version = &amp;#34;0.12.0&amp;#34;, default-features = false }&lt;br/&gt;tempfile = &amp;#34;3.27.0&amp;#34;&lt;br/&gt;rand = &amp;#34;0.8&amp;#34;&lt;br/&gt;frost-secp256k1-tr = &amp;#34;3.0.0-rc.0&amp;#34;&lt;br/&gt;serial_test = { version = &amp;#34;3.4.0&amp;#34;, features = [&amp;#34;test_logging&amp;#34;] }&lt;br/&gt;log = &amp;#34;0.4&amp;#34;&lt;br/&gt;&lt;br/&gt;[dependencies]&lt;br/&gt;get_file_hash_core = { workspace = true, features = [&amp;#34;nostr&amp;#34;]  }&lt;br/&gt;sha2 = { workspace = true }&lt;br/&gt;nostr = { workspace = true, optional = true }&lt;br/&gt;nostr-sdk = { workspace = true, optional = true }&lt;br/&gt;hex = { workspace = true, optional = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;full&amp;#34;] }&lt;br/&gt;frost-secp256k1-tr = { workspace = true }&lt;br/&gt;rand = { workspace = true }&lt;br/&gt;serde_json = { workspace = true }&lt;br/&gt;rand_chacha = { workspace = true }&lt;br/&gt;&lt;br/&gt;[build-dependencies]&lt;br/&gt;get_file_hash_core = { workspace = true, features = [&amp;#34;nostr&amp;#34;] }&lt;br/&gt;sha2 = { workspace = true }&lt;br/&gt;serde_json = { workspace = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;full&amp;#34;] }&lt;br/&gt;nostr = { workspace = true }&lt;br/&gt;nostr-sdk = { workspace = true }&lt;br/&gt;hex = { workspace = true }&lt;br/&gt;&lt;br/&gt;# The profile that &amp;#39;dist&amp;#39; will build with&lt;br/&gt;[profile.dist]&lt;br/&gt;inherits = &amp;#34;release&amp;#34;&lt;br/&gt;lto = &amp;#34;thin&amp;#34;&lt;br/&gt;&lt;br/&gt;[dev-dependencies]&lt;br/&gt;serial_test = { workspace = true }&lt;br/&gt;&lt;br/&gt;[[example]]&lt;br/&gt;name = &amp;#34;gnostr-build&amp;#34;&lt;br/&gt;path = &amp;#34;examples/gnostr-build.rs&amp;#34;&lt;br/&gt;required-features = [&amp;#34;nostr&amp;#34;]&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:26Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsxu68dwtuva5ends5m70ndy86zcz4pqj2q47vcwvgcn5jnr6yrmcszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjxwwvkd</id>
    
      <title type="html">[package] name = &amp;#34;get_file_hash_core&amp;#34; version = { ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsxu68dwtuva5ends5m70ndy86zcz4pqj2q47vcwvgcn5jnr6yrmcszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjxwwvkd" />
    <content type="html">
      [package]&lt;br/&gt;name = &amp;#34;get_file_hash_core&amp;#34;&lt;br/&gt;version = { workspace = true }&lt;br/&gt;edition = { workspace = true }&lt;br/&gt;description = { workspace = true }&lt;br/&gt;license = { workspace = true }&lt;br/&gt;documentation = { workspace = true }&lt;br/&gt;homepage = { workspace = true }&lt;br/&gt;repository = { workspace = true }&lt;br/&gt;authors = { workspace = true }&lt;br/&gt;&lt;br/&gt;[features]&lt;br/&gt;nostr = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:serde_json&amp;#34;, &amp;#34;dep:sha2&amp;#34;, &amp;#34;dep:hex&amp;#34;, &amp;#34;dep:reqwest&amp;#34;, &amp;#34;dep:tokio&amp;#34;, &amp;#34;dep:csv&amp;#34;, &amp;#34;dep:url&amp;#34;, &amp;#34;dep:frost-secp256k1-tr&amp;#34;, &amp;#34;dep:rand&amp;#34;]&lt;br/&gt;frost = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:serde_json&amp;#34;, &amp;#34;dep:sha2&amp;#34;, &amp;#34;dep:hex&amp;#34;, &amp;#34;dep:reqwest&amp;#34;, &amp;#34;dep:tokio&amp;#34;, &amp;#34;dep:csv&amp;#34;, &amp;#34;dep:url&amp;#34;, &amp;#34;dep:frost-secp256k1-tr&amp;#34;, &amp;#34;dep:rand&amp;#34;]&lt;br/&gt;&lt;br/&gt;[dependencies]&lt;br/&gt;sha2 = { workspace = true, optional = true }&lt;br/&gt;nostr = { workspace = true, optional = true }&lt;br/&gt;serde_json = { workspace = true, optional = true }&lt;br/&gt;nostr-sdk = { workspace = true, optional = true }&lt;br/&gt;hex = { workspace = true, optional = true }&lt;br/&gt;csv = { workspace = true, optional = true }&lt;br/&gt;url = { workspace = true, optional = true }&lt;br/&gt;frost-secp256k1-tr = { workspace = true, optional = true }&lt;br/&gt;rand = { workspace = true, optional = true }&lt;br/&gt;&lt;br/&gt;[dev-dependencies]&lt;br/&gt;sha2 = { workspace = true }&lt;br/&gt;tempfile = { workspace = true }&lt;br/&gt;nostr = { workspace = true }&lt;br/&gt;nostr-sdk = { workspace = true }&lt;br/&gt;serde_json = { workspace = true }&lt;br/&gt;hex = { workspace = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;macros&amp;#34;, &amp;#34;rt-multi-thread&amp;#34;] }&lt;br/&gt;csv = { workspace = true }&lt;br/&gt;url = { workspace = true }&lt;br/&gt;frost-secp256k1-tr = { workspace = true }&lt;br/&gt;serial_test = { workspace = true, features = [&amp;#34;test_logging&amp;#34;] }&lt;br/&gt;log = { workspace = true }&lt;br/&gt;&lt;br/&gt;[build-dependencies]&lt;br/&gt;reqwest = { workspace = true, features = [&amp;#34;json&amp;#34;], optional = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;macros&amp;#34;, &amp;#34;rt-multi-thread&amp;#34;], optional = true }&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:20Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsqvqnckvphuf4g88spzsf973wvanerztfvtx3az9jhvp8nhpm9mcgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjps22tu</id>
    
      <title type="html">//! A crate providing the `get_file_hash!` procedural macro. //! ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsqvqnckvphuf4g88spzsf973wvanerztfvtx3az9jhvp8nhpm9mcgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjps22tu" />
    <content type="html">
      //! A crate providing the `get_file_hash!` procedural macro.&lt;br/&gt;//!&lt;br/&gt;//! This macro allows you to compute the SHA-256 hash of a file at compile time,&lt;br/&gt;//! embedding the resulting hash string directly into your Rust executable.&lt;br/&gt;&lt;br/&gt;pub use get_file_hash_core::get_file_hash;&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `build.rs` at the time of compilation.&lt;br/&gt;pub const BUILD_HASH: &amp;amp;str = env!(&amp;#34;BUILD_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `Cargo.toml` at the time of compilation.&lt;br/&gt;pub const CARGO_TOML_HASH: &amp;amp;str = env!(&amp;#34;CARGO_TOML_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `src/lib.rs` at the time of compilation.&lt;br/&gt;pub const LIB_HASH: &amp;amp;str = env!(&amp;#34;LIB_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The name of the package as specified in Cargo.toml.&lt;br/&gt;pub const CARGO_PKG_NAME: &amp;amp;str = env!(&amp;#34;CARGO_PKG_NAME&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The version of the package as specified in Cargo.toml.&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;/// The git commit hash of the repository at the time of compilation.&lt;br/&gt;pub const GIT_COMMIT_HASH: &amp;amp;str = env!(&amp;#34;GIT_COMMIT_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;/// The git branch of the repository at the time of compilation.&lt;br/&gt;pub const GIT_BRANCH: &amp;amp;str = env!(&amp;#34;GIT_BRANCH&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(test)]&lt;br/&gt;mod tests {&lt;br/&gt;    use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;    use super::*;&lt;br/&gt;&lt;br/&gt;    /// Verifies that the exported CARGO_TOML_HASH is not empty.&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_injected_hash_exists() {&lt;br/&gt;        assert!(!BUILD_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified build.rs Hash:&lt;br/&gt;{}&amp;#34;, BUILD_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_TOML_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Cargo.toml Hash:&lt;br/&gt;{}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!LIB_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified src/lib.rs Hash:\n{}&amp;#34;, LIB_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_PKG_NAME.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Package Name:\n{}&amp;#34;, CARGO_PKG_NAME);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_PKG_VERSION.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Package Version:\n{}&amp;#34;, CARGO_PKG_VERSION);&lt;br/&gt;&lt;br/&gt;        #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;        {&lt;br/&gt;            assert!(!GIT_COMMIT_HASH.is_empty());&lt;br/&gt;            println!(&amp;#34;Verified Git Commit Hash:\n{}&amp;#34;, GIT_COMMIT_HASH);&lt;br/&gt;&lt;br/&gt;            assert!(!GIT_BRANCH.is_empty());&lt;br/&gt;            println!(&amp;#34;Verified Git Branch:\n{}&amp;#34;, GIT_BRANCH);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// Tests that the `get_file_hash!` macro correctly computes the SHA-256&lt;br/&gt;    /// hash of `lib.rs` and that it matches a manually computed hash of the&lt;br/&gt;    /// same file.&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_get_lib_hash() {&lt;br/&gt;        let file_content = include_bytes!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let mut hasher = Sha256::new();&lt;br/&gt;        hasher.update(file_content);&lt;br/&gt;        let expected_hash = hasher&lt;br/&gt;            .finalize()&lt;br/&gt;            .iter()&lt;br/&gt;            .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;            .collect::&amp;lt;String&amp;gt;();&lt;br/&gt;&lt;br/&gt;        let actual_hash = get_file_hash!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;        assert_eq!(actual_hash, expected_hash);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:20Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsqrys9p0szah4fmjly8crrja2gkervxrnwsez9mhsjn9hq7yz0kfczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjqtwsvl</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsqrys9p0szah4fmjly8crrja2gkervxrnwsez9mhsjn9hq7yz0kfczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjqtwsvl" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_pr_update;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let pr_event_id = EventId::from_str(&amp;#34;f6e4d6a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9&amp;#34;).unwrap(); // Example PR Event ID&lt;br/&gt;    let updated_commit_id = &amp;#34;z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0&amp;#34;;&lt;br/&gt;    let updated_clone_url = &amp;#34;git@github.com:user/my-feature-branch-v2.git&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_pr_update --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:19Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsq4ghxv7lw446vc73qjzqgfmzm4fylzur3y6l03pfhlymz5pt5k3qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjnhr9np</id>
    
      <title type="html">Relay URL,Latitude,Longitude wot.nostr.party,36.1627,-86.7816 ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsq4ghxv7lw446vc73qjzqgfmzm4fylzur3y6l03pfhlymz5pt5k3qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjnhr9np" />
    <content type="html">
      Relay URL,Latitude,Longitude&lt;br/&gt;wot.nostr.party,36.1627,-86.7816&lt;br/&gt;nostr.simplex.icu,50.1109,8.68213&lt;br/&gt;relay.snort.social,53.3498,-6.26031&lt;br/&gt;nostr.stakey.net,52.3676,4.90414&lt;br/&gt;relay.mccormick.cx,52.3563,4.95714&lt;br/&gt;nostr.overmind.lol,43.6532,-79.3832&lt;br/&gt;nostriches.club,43.6532,-79.3832&lt;br/&gt;kanagrovv-pyramid.kozow.com,43.4305,-83.9638&lt;br/&gt;relay.toastr.net,40.8054,-74.0241&lt;br/&gt;relay.primal.net,43.6532,-79.3832&lt;br/&gt;r.bitcoinhold.net,43.6532,-79.3832&lt;br/&gt;wot.dtonon.com,43.6532,-79.3832&lt;br/&gt;santo.iguanatech.net,40.8302,-74.1299&lt;br/&gt;relay2.ngengine.org,43.6532,-79.3832&lt;br/&gt;nostr.oxtr.dev,50.4754,12.3683&lt;br/&gt;simplex.icu,50.1109,8.68213&lt;br/&gt;bitchat.nostr1.com,38.6327,-90.1961&lt;br/&gt;relay.nostu.be,40.4167,-3.70329&lt;br/&gt;nostr.mifen.me,43.6532,-79.3832&lt;br/&gt;relay.vantis.ninja,43.6532,-79.3832&lt;br/&gt;nostr-kyomu-haskell.onrender.com,37.7775,-122.397&lt;br/&gt;nostr-relay.amethyst.name,39.0067,-77.4291&lt;br/&gt;relay.bitcoindistrict.org,43.6532,-79.3832&lt;br/&gt;nos.xmark.cc,50.6924,3.20113&lt;br/&gt;relay01.lnfi.network,35.6764,139.65&lt;br/&gt;nostr-dev.wellorder.net,45.5201,-122.99&lt;br/&gt;nostr.rblb.it,43.7094,10.6582&lt;br/&gt;offchain.pub,39.1585,-94.5728&lt;br/&gt;wot.nostr.place,32.7767,-96.797&lt;br/&gt;fanfares.nostr1.com,38.6327,-90.1961&lt;br/&gt;ephemeral.snowflare.cc,43.6532,-79.3832&lt;br/&gt;relay.visionfusen.org,43.6532,-79.3832&lt;br/&gt;nostr.carroarmato0.be,51.0368,3.21186&lt;br/&gt;social.amanah.eblessing.co,48.1046,11.6002&lt;br/&gt;relay.cyphernomad.com,60.4032,25.0321&lt;br/&gt;nostr-rs-relay-qj1h.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ngengine.org,43.6532,-79.3832&lt;br/&gt;relay.nosto.re,51.1792,5.89444&lt;br/&gt;rusty-uat.siberian-albacore.ts.net:8443,35.6764,139.65&lt;br/&gt;nostr.luisschwab.net,43.6532,-79.3832&lt;br/&gt;nostr.aruku.ovh,1.27994,103.849&lt;br/&gt;srtrelay.c-stellar.net,43.6532,-79.3832&lt;br/&gt;nostr.tagomago.me,3.139,101.687&lt;br/&gt;relay.threenine.services,51.5222,-0.62916&lt;br/&gt;nostr.robosats.org,64.1476,-21.9392&lt;br/&gt;nostr.2b9t.xyz,34.0549,-118.243&lt;br/&gt;strfry.apps3.slidestr.net,40.4167,-3.70329&lt;br/&gt;kitchen.zap.cooking,43.6532,-79.3832&lt;br/&gt;relay.homeinhk.xyz,45.5152,-122.678&lt;br/&gt;relay.seq1.net,43.6532,-79.3832&lt;br/&gt;relay.bornheimer.app,50.1109,8.68213&lt;br/&gt;relay.vrtmrz.net,43.6532,-79.3832&lt;br/&gt;nostr.red5d.dev,43.6532,-79.3832&lt;br/&gt;relay-freeharmonypeople.space,38.7223,-9.13934&lt;br/&gt;aaa-api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;dev.relay.edufeed.org,49.4521,11.0767&lt;br/&gt;nostr.myshosholoza.co.za,52.3913,4.66545&lt;br/&gt;nostr.plantroon.com,50.1013,8.62643&lt;br/&gt;wot.dergigi.com,64.1476,-21.9392&lt;br/&gt;npub1spxdug4m3y24hpx5crm0el4zhkk0wafs8kp6m0xu0wecygqej2xqq8gyhx.fips.network,43.6532,-79.3832&lt;br/&gt;nostrelay.circum.space,52.3676,4.90414&lt;br/&gt;relay.dreamith.to,43.6532,-79.3832&lt;br/&gt;relay.nostriches.club,43.6532,-79.3832&lt;br/&gt;nostr-relayrs.gateway.in.th,15.5163,103.194&lt;br/&gt;nostr.chrissexton.org,43.6532,-79.3832&lt;br/&gt;relay.flashapp.me,43.652,-79.3633&lt;br/&gt;nostr-relay-1.trustlessenterprise.com,43.6532,-79.3832&lt;br/&gt;strfry.shock.network,39.0438,-77.4874&lt;br/&gt;relay.snotr.nl:49999,52.0195,4.42946&lt;br/&gt;spatia-arcana.com,34.0362,-118.443&lt;br/&gt;nostr.computingcache.com,34.0356,-118.442&lt;br/&gt;nostr.self-determined.de,53.5,10.25&lt;br/&gt;relay.sharegap.net,43.6532,-79.3832&lt;br/&gt;spookstr2.nostr1.com,38.6327,-90.1961&lt;br/&gt;v-relay.d02.vrtmrz.net,34.6937,135.502&lt;br/&gt;bridge.tagomago.me,3.139,101.687&lt;br/&gt;antiprimal.net,43.6532,-79.3832&lt;br/&gt;relay.nostrdice.com,-33.8688,151.209&lt;br/&gt;purpura.cloud,43.6532,-79.3832&lt;br/&gt;espelho.girino.org,43.6532,-79.3832&lt;br/&gt;relay.mostro.network,40.8302,-74.1299&lt;br/&gt;temp.iris.to,43.6532,-79.3832&lt;br/&gt;pyramid.self-determined.de,53.5,10.25&lt;br/&gt;relay.jeffg.fyi,43.6532,-79.3832&lt;br/&gt;nostr.aruku.kro.kr,37.3589,127.115&lt;br/&gt;chat-relay.zap-work.com,43.6532,-79.3832&lt;br/&gt;relay.islandbitcoin.com,12.8498,77.6545&lt;br/&gt;nostr.zoracle.org,45.6018,-121.185&lt;br/&gt;relay-dev.satlantis.io,40.8302,-74.1299&lt;br/&gt;relay.earthly.city,34.0362,-118.443&lt;br/&gt;speakeasy.cellar.social,49.4543,11.0746&lt;br/&gt;relay.bnos.space,43.6532,-79.3832&lt;br/&gt;relay.henryxplace.eu.org:9988,31.2304,121.474&lt;br/&gt;relay.bitmacro.cloud,43.6532,-79.3832&lt;br/&gt;nostr.thebiglake.org,32.71,-96.6745&lt;br/&gt;relay.lab.rytswd.com,49.4543,11.0746&lt;br/&gt;nostr.nadajnik.org,50.1109,8.68213&lt;br/&gt;relay.evanverma.com,40.8302,-74.1299&lt;br/&gt;relay2.angor.io,48.1046,11.6002&lt;br/&gt;prl.plus,55.7628,37.5983&lt;br/&gt;myvoiceourstory.org,37.3598,-121.981&lt;br/&gt;relay.arx-ccn.com,50.4754,12.3683&lt;br/&gt;wot.sudocarlos.com,43.6532,-79.3832&lt;br/&gt;relayrs.notoshi.win,43.6532,-79.3832&lt;br/&gt;nostrcity-club.fly.dev,48.8575,2.35138&lt;br/&gt;relay.tagayasu.xyz,45.4215,-75.6972&lt;br/&gt;nostr.blankfors.se,60.1699,24.9384&lt;br/&gt;nrs-01.darkcloudarcade.com,39.1008,-94.5811&lt;br/&gt;relay.lightning.pub,39.0438,-77.4874&lt;br/&gt;nostr-02.yakihonne.com,1.32123,103.695&lt;br/&gt;relay.nostrverse.net,43.6532,-79.3832&lt;br/&gt;nostr.wecsats.io,43.6532,-79.3832&lt;br/&gt;relay.illuminodes.com,47.6062,-122.332&lt;br/&gt;api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;nostr-relay.psfoundation.info,39.0438,-77.4874&lt;br/&gt;relay.samt.st,40.8302,-74.1299&lt;br/&gt;nostr-relay.cbrx.io,43.6532,-79.3832&lt;br/&gt;inbox.mycelium.social,38.627,-90.1994&lt;br/&gt;relay.anmore.me,49.281,-123.117&lt;br/&gt;no.str.cr,10.074,-84.2155&lt;br/&gt;nstr.a0a1.space,52.3563,4.95714&lt;br/&gt;relay.typedcypher.com,51.5072,-0.127586&lt;br/&gt;relay.bitmacro.pro,43.6532,-79.3832&lt;br/&gt;relay.nostrzh.org,43.6532,-79.3832&lt;br/&gt;ynostr.yael.at,60.1699,24.9384&lt;br/&gt;nostr-relay.zeabur.app,25.0797,121.234&lt;br/&gt;dynasty.libretechsystems.xyz,55.4724,9.87335&lt;br/&gt;nostr.bitcoiner.social,47.6743,-117.112&lt;br/&gt;nostr.girino.org,43.6532,-79.3832&lt;br/&gt;nostr2.girino.org,43.6532,-79.3832&lt;br/&gt;nostr-verified.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.fundstr.me,42.3601,-71.0589&lt;br/&gt;relay.mapboss.co.th,13.7234,100.784&lt;br/&gt;relay.qstr.app,51.5072,-0.127586&lt;br/&gt;nostr-rs-relay-ishosta.phamthanh.me,43.6532,-79.3832&lt;br/&gt;relay.klabo.world,47.674,-122.122&lt;br/&gt;relay.minibolt.info,43.6532,-79.3832&lt;br/&gt;x.kojira.io,43.6532,-79.3832&lt;br/&gt;relay-dev.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostriot.com,41.5695,-83.9786&lt;br/&gt;relayone.soundhsa.com,39.1008,-94.5811&lt;br/&gt;nr.yay.so,46.2126,6.1154&lt;br/&gt;relay.bithome.site,52.3563,4.95714&lt;br/&gt;relay.damus.io,43.6532,-79.3832&lt;br/&gt;nostr.mikoshi.de,50.1109,8.68213&lt;br/&gt;nostr.defucc.me,50.1109,8.68213&lt;br/&gt;relay.malxte.de,52.52,13.405&lt;br/&gt;relay.orangepill.ovh,49.1689,-0.358841&lt;br/&gt;bbw-nostr.xyz,41.5284,-87.4237&lt;br/&gt;kasztanowa.bieda.it,43.6532,-79.3832&lt;br/&gt;bitcoiner.social,47.6743,-117.112&lt;br/&gt;relay.lacompagniemaximus.com,45.3147,-73.8785&lt;br/&gt;relay.mostr.pub,43.6532,-79.3832&lt;br/&gt;relay.lanavault.space,60.1699,24.9384&lt;br/&gt;kotukonostr.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ditto.pub,43.6532,-79.3832&lt;br/&gt;relay.erybody.com,41.4513,-81.7021&lt;br/&gt;nostr.dlcdevkit.com,40.0992,-83.1141&lt;br/&gt;ribo.us.nostria.app,41.5868,-93.625&lt;br/&gt;relay.paulstephenborile.com,49.4543,11.0746&lt;br/&gt;testnet-relay.samt.st,40.8302,-74.1299&lt;br/&gt;relay.purplefrog.cloud,35.6916,139.768&lt;br/&gt;relay.agorist.space,52.3734,4.89406&lt;br/&gt;nostr-relay.zimage.com,34.0549,-118.243&lt;br/&gt;nostr.azzamo.net,52.2633,21.0283&lt;br/&gt;strfry.elswa-dev.online,50.1109,8.68213&lt;br/&gt;wot.shaving.kiwi,43.6532,-79.3832&lt;br/&gt;okn.czas.plus,50.1109,8.68213&lt;br/&gt;bcast.seutoba.com.br,43.6532,-79.3832&lt;br/&gt;relay.sigit.io,50.4754,12.3683&lt;br/&gt;syb.lol,34.0549,-118.243&lt;br/&gt;relay.libernet.app,43.6532,-79.3832&lt;br/&gt;relay.angor.io,48.1046,11.6002&lt;br/&gt;relay.staging.commonshub.brussels,49.4543,11.0746&lt;br/&gt;strfry.atlantislabs.space,43.6532,-79.3832&lt;br/&gt;nostr.wom.wtf,43.6532,-79.3832&lt;br/&gt;nostrride.io,37.3986,-121.964&lt;br/&gt;nostr.dpinkerton.com,39.1008,-94.5811&lt;br/&gt;r.0kb.io,32.789,-96.7989&lt;br/&gt;nostr.hekster.org,37.3986,-121.964&lt;br/&gt;satsage.xyz,37.3986,-121.964&lt;br/&gt;nostr.islandarea.net,35.4669,-97.6473&lt;br/&gt;ve.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.openfarmtools.org,60.1699,24.9384&lt;br/&gt;top.testrelay.top,43.6532,-79.3832&lt;br/&gt;relay-rpi.edufeed.org,49.4521,11.0767&lt;br/&gt;pyramid.cult.cash,32.9483,-96.7299&lt;br/&gt;relay.edino.net,56.6268,47.9193&lt;br/&gt;nostr.snowbla.de,60.1699,24.9384&lt;br/&gt;relay.wavefunc.live,39.7392,-104.99&lt;br/&gt;tenex.chat,50.4754,12.3683&lt;br/&gt;relay.getsafebox.app,43.6532,-79.3832&lt;br/&gt;nostr.bond,50.1109,8.68213&lt;br/&gt;nostrelites.org,41.8781,-87.6298&lt;br/&gt;relay.plebeian.market,50.1109,8.68213&lt;br/&gt;relay.laantungir.net,-19.4692,-42.5315&lt;br/&gt;relay.decentnewsroom.com,50.4754,12.3683&lt;br/&gt;nostr-relay.nextblockvending.com,47.2343,-119.853&lt;br/&gt;relay.spacetomatoes.net,42.3601,-71.0589&lt;br/&gt;nostrbtc.com,43.6532,-79.3832&lt;br/&gt;relay.puresignal.news,43.6532,-79.3832&lt;br/&gt;relay-testnet.k8s.layer3.news,37.3387,-121.885&lt;br/&gt;relay.binaryrobot.com,43.6532,-79.3832&lt;br/&gt;relay.wavlake.com,41.2619,-95.8608&lt;br/&gt;inbox.scuba323.com,40.8218,-74.45&lt;br/&gt;nostr.spaceshell.xyz,43.6532,-79.3832&lt;br/&gt;relay.nostr.place,32.7767,-96.797&lt;br/&gt;holland-excited-charming-experiencing.trycloudflare.com,43.6532,-79.3832&lt;br/&gt;theoutpost.life,64.1476,-21.9392&lt;br/&gt;relay.fckstate.net,59.3293,18.0686&lt;br/&gt;bcast.girino.org,43.6532,-79.3832&lt;br/&gt;discovery.us.nostria.app,52.3676,4.90414&lt;br/&gt;relay.bullishbounty.com,43.6532,-79.3832&lt;br/&gt;nostr.88mph.life,51.5072,-0.127586&lt;br/&gt;nostr.tadryanom.me,43.6532,-79.3832&lt;br/&gt;nostr.sathoarder.com,48.5734,7.75211&lt;br/&gt;relay.nostr.net,43.6532,-79.3832&lt;br/&gt;zw.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.internationalright-wing.org,-22.5022,-48.7114&lt;br/&gt;nostr.vulpem.com,49.4543,11.0746&lt;br/&gt;wot.codingarena.top,50.4754,12.3683&lt;br/&gt;reraw.pbla2fish.cc,43.6532,-79.3832&lt;br/&gt;plebchain.club,43.6532,-79.3832&lt;br/&gt;orly-relay.imwald.eu,48.8575,2.35138&lt;br/&gt;relay.satnam.pub,43.6532,-79.3832&lt;br/&gt;cs-relay.nostrdev.com,50.4754,12.3683&lt;br/&gt;schnorr.me,43.6532,-79.3832&lt;br/&gt;nostr-relay.online,43.6532,-79.3832&lt;br/&gt;relay.routstr.com,43.6532,-79.3832&lt;br/&gt;relay.ohstr.com,43.6532,-79.3832&lt;br/&gt;relay.lanacoin-eternity.com,40.8302,-74.1299&lt;br/&gt;wot.nostr.net,43.6532,-79.3832&lt;br/&gt;nostr.ps1829.com,33.8851,130.883&lt;br/&gt;yabu.me,35.6092,139.73&lt;br/&gt;soloco.nl,43.6532,-79.3832&lt;br/&gt;librerelay.aaroniumii.com,43.6532,-79.3832&lt;br/&gt;relay.mmwaves.de,48.8575,2.35138&lt;br/&gt;relay.artx.market,43.6548,-79.3885&lt;br/&gt;nostr.jerrynya.fun,31.2304,121.474&lt;br/&gt;relay-arg.zombi.cloudrodion.com,1.35208,103.82&lt;br/&gt;relay.edufeed.org,49.4521,11.0767&lt;br/&gt;discovery.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.layer.systems,49.0291,8.35695&lt;br/&gt;nostr-rs-relay.dev.fedibtc.com,39.0438,-77.4874&lt;br/&gt;relay.0xchat.com,43.6532,-79.3832&lt;br/&gt;nos.lol,50.4754,12.3683&lt;br/&gt;lightning.red,53.3498,-6.26031&lt;br/&gt;slick.mjex.me,39.0418,-77.4744&lt;br/&gt;relay.boredvictor.xyz,41.3888,2.15899&lt;br/&gt;nostr.rtvslawenia.com,49.4543,11.0746&lt;br/&gt;relay.mitchelltribe.com,39.0438,-77.4874&lt;br/&gt;nostr.4rs.nl,49.0291,8.35696&lt;br/&gt;relay.olas.app,50.4754,12.3683&lt;br/&gt;memlay.v0l.io,53.3498,-6.26031&lt;br/&gt;nostr-01.yakihonne.com,1.29524,103.79&lt;br/&gt;relay.satmaxt.xyz,43.6532,-79.3832&lt;br/&gt;nostrcheck.tnsor.network,43.6532,-79.3832&lt;br/&gt;relay.guggero.org,46.0037,8.95105&lt;br/&gt;ai.techunder.tech:56711,22.5429,114.06&lt;br/&gt;premium.primal.net,43.6532,-79.3832&lt;br/&gt;nostr.tac.lol,47.4748,-122.273&lt;br/&gt;relay.zone667.com,60.1699,24.9384&lt;br/&gt;nostr-relay.gateway.in.th,15.5163,103.194&lt;br/&gt;vault.iris.to,43.6532,-79.3832&lt;br/&gt;strfry.bonsai.com,37.8716,-122.273&lt;br/&gt;ribo.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.tapestry.ninja,40.8054,-74.0241&lt;br/&gt;relay.dwadziesciajeden.pl,52.2297,21.0122&lt;br/&gt;relay.satlantis.io,32.8769,-80.0114&lt;br/&gt;nostr.pbfs.io,50.4754,12.3683&lt;br/&gt;freelay.sovbit.host,64.1476,-21.9392&lt;br/&gt;articles.layer3.news,37.3387,-121.885&lt;br/&gt;nostr.na.social,43.6532,-79.3832&lt;br/&gt;relay.fountain.fm,43.6532,-79.3832&lt;br/&gt;dev.relay.stream,43.6532,-79.3832&lt;br/&gt;nostr.n7ekb.net,36.1527,-95.9902&lt;br/&gt;relay5.bitransfer.org,43.6532,-79.3832&lt;br/&gt;relay.og.coop,43.6532,-79.3832&lt;br/&gt;nostr-server-production.up.railway.app,45.5019,-73.5674&lt;br/&gt;bucket.coracle.social,37.7775,-122.397&lt;br/&gt;relay.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostr-check.me,43.6532,-79.3832&lt;br/&gt;nostr.faultables.net,43.6532,-79.3832&lt;br/&gt;strfry.openhoofd.nl,51.9229,4.40833&lt;br/&gt;nostr.rblb.it:7777,43.7094,10.6582&lt;br/&gt;relay.nostrcheck.me,43.6532,-79.3832&lt;br/&gt;0x-nostr-relay.fly.dev,48.8575,2.35138&lt;br/&gt;nostr.thalheim.io,60.1699,24.9384&lt;br/&gt;relay-nl.zombi.cloudrodion.com,50.8943,6.06237&lt;br/&gt;relay.shadowbip.com,51.5072,-0.127586&lt;br/&gt;nostr-relay.corb.net,38.8353,-104.822&lt;br/&gt;purplerelay.com,43.6532,-79.3832&lt;br/&gt;nostr-pub.wellorder.net,45.5201,-122.99&lt;br/&gt;herbstmeister.com,34.0549,-118.243&lt;br/&gt;nostrcheck.me,43.6532,-79.3832&lt;br/&gt;pyramid.nostr.technology,52.3947,4.66399&lt;br/&gt;nostr.spicyz.io,43.6532,-79.3832&lt;br/&gt;nrs-02.darkcloudarcade.com,39.9526,-75.1652&lt;br/&gt;nestr.nedao.ch,47.0151,6.98832&lt;br/&gt;nostr.nodesmap.com,59.3327,18.0656&lt;br/&gt;nittom.nostr1.com,38.6327,-90.1961&lt;br/&gt;public.crostr.com,43.6532,-79.3832&lt;br/&gt;relay.cypherflow.ai,48.8575,2.35138&lt;br/&gt;nostr.bitczat.pl,60.1699,24.9384&lt;br/&gt;relayone.geektank.ai,39.1008,-94.5811&lt;br/&gt;testrelay.era21.space,43.6532,-79.3832&lt;br/&gt;relay.npubhaus.com,43.6532,-79.3832&lt;br/&gt;relay.bitmacro.io,48.8566,2.35222&lt;br/&gt;nostr.data.haus,50.4754,12.3683&lt;br/&gt;relay.credenso.cafe,43.3601,-80.3127&lt;br/&gt;relay.ru.ac.th,13.7607,100.627&lt;br/&gt;relay-fra.zombi.cloudrodion.com,48.8566,2.35222&lt;br/&gt;nostr.chaima.info,50.1109,8.68213&lt;br/&gt;nostr.mom,50.4754,12.3683
    </content>
    <updated>2026-04-04T01:41:09Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs2hjzf3ayu7mh7essn9n9u622g9v2fjgxcar5lzx4qvdphs0rchvqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjeysgv6</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs2hjzf3ayu7mh7essn9n9u622g9v2fjgxcar5lzx4qvdphs0rchvqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjeysgv6" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use get_file_hash_core::{get_relay_urls, publish_patch, publish_metadata_event, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-gnostr-repository-patch-with-metadata-example&amp;#34;; // Repository identifier&lt;br/&gt;    let commit_id = &amp;#34;f1e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6b7a8f9e0&amp;#34;; // Example commit ID&lt;br/&gt;&lt;br/&gt;    // Metadata for NIP-01 event&lt;br/&gt;    let picture_url = DEFAULT_PICTURE_URL;&lt;br/&gt;    let banner_url = DEFAULT_BANNER_URL;&lt;br/&gt;    let metadata_file_path = &amp;#34;./README.md&amp;#34;; // Using README.md content for metadata&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Publishing NIP-01 Metadata Event...&amp;#34;);&lt;br/&gt;    publish_metadata_event(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        picture_url,&lt;br/&gt;        banner_url,&lt;br/&gt;        metadata_file_path&lt;br/&gt;    ).await;&lt;br/&gt;    println!(&amp;#34;NIP-01 Metadata Event published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;&lt;br/&gt;Publishing NIP-34 Patch Event without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use an existing file for the patch content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;NIP-34 Patch Event without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;&lt;br/&gt;Publishing NIP-34 Patch Event with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;NIP-34 Patch Event with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_patch_with_metadata --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:08Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs8x7japn8km8twff83hxcf34a6544j3yjvj568wchj3atke7eh9hszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjeazgx5</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs8x7japn8km8twff83hxcf34a6544j3yjvj568wchj3atke7eh9hszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjeazgx5" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;use get_file_hash::{BUILD_HASH, CARGO_TOML_HASH, LIB_HASH};&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART0: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use get_file_hash::CARGO_TOML_HASH;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let readme_hash = get_file_hash!(&amp;#34;src/bin/readme.rs&amp;#34;);&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, lib_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/bin/readme.rs is: {}&amp;#34;, readme_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of Cargo.toml is: {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r&amp;#34;## Release&lt;br/&gt;## [`README.md`](./README.md)&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin readme &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## [`src/bin/readme.rs`](src/bin/readme.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/readme.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`build.rs`](build.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `build.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART3: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`Cargo.toml`](Cargo.toml)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `Cargo.toml`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART4: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`src/lib.rs`](src/lib.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/lib.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART_NIP34: &amp;amp;str = r&amp;#34;## NIP-34 Integration: Git Repository Events on Nostr&lt;br/&gt;&lt;br/&gt;This library provides a set of powerful macros and functions for integrating Git repository events with the Nostr protocol, adhering to the [NIP-34: Git Repositories on Nostr](&lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/34.md&#34;&gt;https://github.com/nostr-protocol/nips/blob/master/34.md&lt;/a&gt;) specification.&lt;br/&gt;&lt;br/&gt;These tools allow you to publish various Git-related events to Nostr relays, enabling decentralized tracking and collaboration for your code repositories.&lt;br/&gt;&lt;br/&gt;### Available NIP-34 Macros&lt;br/&gt;&lt;br/&gt;Each macro provides a convenient way to publish specific NIP-34 event kinds:&lt;br/&gt;&lt;br/&gt;*   [`repository_announcement!`](#repository_announcement)&lt;br/&gt;    *   Publishes a `Repository Announcement` event (Kind 30617) to announce a new or updated Git repository.&lt;br/&gt;*   [`publish_patch!`](#publish_patch)&lt;br/&gt;    *   Publishes a `Patch` event (Kind 1617) containing a Git patch (diff) for a specific commit.&lt;br/&gt;*   [`publish_pull_request!`](#publish_pull_request)&lt;br/&gt;    *   Publishes a `Pull Request` event (Kind 1618) to propose changes and facilitate code review.&lt;br/&gt;*   [`publish_pr_update!`](#publish_pr_update)&lt;br/&gt;    *   Publishes a `Pull Request Update` event (Kind 1619) to update an existing pull request.&lt;br/&gt;*   [`publish_repository_state!`](#publish_repository_state)&lt;br/&gt;    *   Publishes a `Repository State` event (Kind 1620) to announce the current state of a branch (e.g., its latest commit).&lt;br/&gt;*   [`publish_issue!`](#publish_issue)&lt;br/&gt;    *   Publishes an `Issue` event (Kind 1621) to report bugs, request features, or track tasks.&lt;br/&gt;&lt;br/&gt;### Running NIP-34 Examples&lt;br/&gt;&lt;br/&gt;To see these macros in action, navigate to the `examples/` directory and run each example individually with the `nostr` feature enabled:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --example repository_announcement --features nostr&lt;br/&gt;cargo run --example publish_patch --features nostr&lt;br/&gt;cargo run --example publish_pull_request --features nostr&lt;br/&gt;cargo run --example publish_pr_update --features nostr&lt;br/&gt;cargo run --example publish_repository_state --features nostr&lt;br/&gt;cargo run --example publish_issue --features nostr&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`readme.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;readme.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    let build_message = if BUILD_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let cargo_message = if CARGO_TOML_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let lib_message = if LIB_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}{}&amp;#34;, README_TEMPLATE_PART0, README_TEMPLATE_PART1, README_TEMPLATE_PART_NIP34);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, BUILD_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, build_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART3);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, cargo_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART4);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, LIB_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, lib_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:07Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs85kfektzsf24qedk225trlf2cmew66age6s6f97vkj4qhdg7xjqszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj4utf9r</id>
    
      <title type="html"># `build.rs` Documentation This document explains the ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs85kfektzsf24qedk225trlf2cmew66age6s6f97vkj4qhdg7xjqszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj4utf9r" />
    <content type="html">
      # `build.rs` Documentation&lt;br/&gt;&lt;br/&gt;This document explains the functionality of the `build.rs` script in this project. The `build.rs` script is a special Rust file that, if present, Cargo will compile and run *before* compiling the rest of your package. It&amp;#39;s typically used for tasks that need to be performed during the build process, such as generating code, setting environment variables, or performing conditional compilation.&lt;br/&gt;&lt;br/&gt;## Core Functionality&lt;br/&gt;&lt;br/&gt;The `build.rs` script in this project performs the following key functions:&lt;br/&gt;&lt;br/&gt;1.  **Environment Variable Injection:** It computes various project-related values at compile time and injects them as environment variables (`CARGO_RUSTC_ENV=...`) that can be accessed by the main crate using `env!(&amp;#34;VAR_NAME&amp;#34;)`. This includes:&lt;br/&gt;    *   `CARGO_PKG_NAME`: The name of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `CARGO_PKG_VERSION`: The version of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `GIT_COMMIT_HASH`: The full commit hash of the current Git HEAD (if in a Git repository).&lt;br/&gt;    *   `GIT_BRANCH`: The name of the current Git branch (if in a Git repository).&lt;br/&gt;    *   `CARGO_TOML_HASH`: The SHA-256 hash of the `Cargo.toml` file.&lt;br/&gt;    *   `LIB_HASH`: The SHA-256 hash of the `src/lib.rs` file.&lt;br/&gt;    *   `BUILD_HASH`: The SHA-256 hash of the `build.rs` file itself.&lt;br/&gt;&lt;br/&gt;2.  **Rerun Conditions:** It tells Cargo when to re-run the build script. This ensures that the injected environment variables and any conditional compilation logic are up-to-date if relevant files change:&lt;br/&gt;    *   `Cargo.toml`&lt;br/&gt;    *   `src/lib.rs`&lt;br/&gt;    *   `build.rs`&lt;br/&gt;    *   `.git/HEAD` (to detect changes in the Git repository like new commits or branch switches).&lt;br/&gt;    *   `src/get_file_hash_core/src/online_relays_gps.csv` (conditionally, if the file exists).&lt;br/&gt;&lt;br/&gt;3.  **Conditional Nostr Event Publishing (Release Builds with `nostr` feature):**&lt;br/&gt;    If the project is being compiled in **release mode (`--release`)** and the **`nostr` feature is enabled (`--features nostr`)**, the `build.rs` script will connect to Nostr relays and publish events. This is intended for &amp;#34;deterministic Nostr event build examples&amp;#34; as indicated by the comments in the file.&lt;br/&gt;&lt;br/&gt;    *   **Relay Management:** It retrieves a list of default relay URLs. During event publishing, it identifies and removes &amp;#34;unfriendly&amp;#34; or unresponsive relays (e.g., those with timeout, connection issues, or spam blocks) from the list for subsequent publications.&lt;br/&gt;    *   **File Hashing and Key Generation:** For each Git-tracked file (when in a Git repository), it computes its SHA-256 hash. This hash is then used to derive a Nostr `SecretKey`.&lt;br/&gt;    *   **Event Creation:**&lt;br/&gt;        *   **Individual File Events:** For each Git-tracked file, a Nostr `text_note` event is created. This event includes tags for:&lt;br/&gt;            *   `#file`: The path of the file.&lt;br/&gt;            *   `#version`: The package version.&lt;br/&gt;            *   `#commit`: The Git commit hash (if in a Git repository).&lt;br/&gt;            *   `#branch`: The Git branch name (if in a Git repository).&lt;br/&gt;        *   **Metadata Event:** It publishes a metadata event using `get_file_hash_core::publish_metadata_event`.&lt;br/&gt;        *   **Linking Event (Build Manifest):** After processing all individual files, if any events were published, a final &amp;#34;build manifest&amp;#34; `text_note` event is created. This event links to all the individual file events that were published during the build using event tags.&lt;br/&gt;    *   **Output Storage:** The JSON representation of successfully published Nostr events (specifically the `EventId`) is saved to `~/.gnostr/build/{package_version}/{file_path_str_sanitized}/{hash}/{public_key}/{event_id}.json`. This provides a local record of what was published.&lt;br/&gt;&lt;br/&gt;### `publish_nostr_event_if_release` Function&lt;br/&gt;&lt;br/&gt;This asynchronous helper function is responsible for:&lt;br/&gt;*   Adding relays to the Nostr client.&lt;br/&gt;*   Connecting to relays.&lt;br/&gt;*   Signing the provided `EventBuilder` to create an `Event`.&lt;br/&gt;*   Sending the event to the configured relays.&lt;br/&gt;*   Logging success or failure for each relay.&lt;br/&gt;*   Identifying and removing unresponsive relays from the `relay_urls` list.&lt;br/&gt;*   Saving the published event&amp;#39;s JSON to the local filesystem.&lt;br/&gt;&lt;br/&gt;### `should_remove_relay` Function&lt;br/&gt;&lt;br/&gt;This helper function determines if a relay should be considered &amp;#34;unfriendly&amp;#34; or unresponsive based on common error messages received during Nostr event publication.&lt;br/&gt;&lt;br/&gt;## Usage&lt;br/&gt;&lt;br/&gt;To prevent &amp;#39;Too many open files&amp;#39; errors, especially during builds and tests involving numerous file operations or subprocesses (like `git ls-files` or parallel test execution), it may be necessary to increase the file descriptor limit.&lt;br/&gt;&lt;br/&gt;*   **For local development**: Run `ulimit -n 4096` in your terminal session before executing `cargo build` or `cargo test`. This setting is session-specific.&lt;br/&gt;*   **For CI environments**: The `.github/workflows/rust.yml` workflow is configured to set `ulimit -n 4096` for relevant test steps to ensure consistent execution.&lt;br/&gt;&lt;br/&gt;The values set by `build.rs` can be accessed in your Rust code (e.g., `src/lib.rs`) at compile time using the `env!` macro. For example:&lt;br/&gt;```rust&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;The Nostr event publishing functionality of `build.rs` is primarily for release builds with the `nostr` feature enabled, allowing for the automatic, deterministic publication of project state to the Nostr network as part of the CI/CD pipeline.&lt;br/&gt;&lt;br/&gt;## Example Commands&lt;br/&gt;&lt;br/&gt;To interact with the `build.rs` script&amp;#39;s features, especially those related to Nostr event publishing, you can use the following `cargo` commands:&lt;br/&gt;&lt;br/&gt;*   **Build in release mode with Nostr feature (verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --workspace --features nostr -vv&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run tests for `get_file_hash_core` sequentially with Nostr feature and verbose logging (as in CI):**&lt;br/&gt;    ```bash&lt;br/&gt;    RUST_LOG=info,nostr_sdk=debug,frost=debug cargo test -p get_file_hash_core --features nostr -- --test-threads 1 --nocapture&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run all workspace tests in release mode with Nostr feature:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --workspace --release --features nostr&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Build `get_file_hash_core` in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run `get_file_hash_core` tests in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:41:06Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs0yw2a7cujxm6q4ew4zppvmjs97j06pahfmvna4gg2mushtx05zuszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj5my6yh</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs0yw2a7cujxm6q4ew4zppvmjs97j06pahfmvna4gg2mushtx05zuszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj5my6yh" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let file_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, file_hash);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;## Setup and Building&lt;br/&gt;&lt;br/&gt;1.  **Clone the repository:**&lt;br/&gt;    ```bash&lt;br/&gt;    git clone &amp;lt;repository-url&amp;gt;&lt;br/&gt;    cd &amp;lt;repository-name&amp;gt;&lt;br/&gt;    ```&lt;br/&gt;2.  **Build the project:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build&lt;br/&gt;    ```&lt;br/&gt;    During the build, `build.rs` will execute and print the hash of `Cargo.toml`.&lt;br/&gt;3.  **Run the example executable:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo run --bin get_file_hash&lt;br/&gt;    ```&lt;br/&gt;    This will print the hash of `src/bin/get_file_hash.rs` to your console.&lt;br/&gt;&lt;br/&gt;## Updating this `README.md`&lt;br/&gt;&lt;br/&gt;The hash information in this `README.md` is automatically generated by running the example executable.&lt;br/&gt;To update it, execute:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin get_file_hash &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## Current File Hash Information (of `src/bin/get_file_hash.rs`)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/get_file_hash.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`get_file_hash.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}&amp;#34;, README_TEMPLATE_PART1, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:52Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsr9yf7slj44xaqqjhx2pfuhrqacytt0yaklrt46hs0cc6ly93tnegzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjdgaucw</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsr9yf7slj44xaqqjhx2pfuhrqacytt0yaklrt46hs0cc6ly93tnegzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjdgaucw" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use get_file_hash_core::{get_git_tracked_files, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event, publish_patch_event};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_patch;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;; // Example commit ID&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use an existing file for the patch content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_patch --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:52Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs8lhgyh8aqjddn3qxmw3mnta9xlqtzj7hcw8slmkrftp4htd7zm5gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjhrfejm</id>
    
      <title>Nostr event nevent1qqs8lhgyh8aqjddn3qxmw3mnta9xlqtzj7hcw8slmkrftp4htd7zm5gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjhrfejm</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs8lhgyh8aqjddn3qxmw3mnta9xlqtzj7hcw8slmkrftp4htd7zm5gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjhrfejm" />
    <content type="html">
      plan-dist-manifest.json&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:46Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsgwz5hswgq7wpucsfpgmna5xwdmqy5gey2pr7emdghxas926hwglczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj82vks4</id>
    
      <title type="html">#![cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsgwz5hswgq7wpucsfpgmna5xwdmqy5gey2pr7emdghxas926hwglczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj82vks4" />
    <content type="html">
      #![cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;use frost::keys::PublicKeyPackage;&lt;br/&gt;use frost::round2::SignatureShare;&lt;br/&gt;use frost::SigningPackage;&lt;br/&gt;use hex;&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;use sha2::Sha256;&lt;br/&gt;use serde_json;&lt;br/&gt;use sha2::Digest;&lt;br/&gt;&lt;br/&gt;pub fn process_relay_share(&lt;br/&gt;    relay_payload_hex: &amp;amp;str,&lt;br/&gt;    signer_id_u16: u16,&lt;br/&gt;    _signing_package: &amp;amp;SigningPackage,&lt;br/&gt;    _pubkey_package: &amp;amp;PublicKeyPackage,&lt;br/&gt;) -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    // In a real scenario, this function would deserialize the share, perform&lt;br/&gt;    // individual verification, and store it for aggregation.&lt;br/&gt;    // For this example, we&amp;#39;ll just acknowledge receipt.&lt;br/&gt;    let _share_bytes = hex::decode(relay_payload_hex)?;&lt;br/&gt;    let _share = SignatureShare::deserialize(&amp;amp;_share_bytes)?;&lt;br/&gt;    let _identifier = frost::Identifier::try_from(signer_id_u16)?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;✅ Share from Signer {} processed (simplified).&amp;#34;, signer_id_u16);&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;pub fn simulate_frost_mailbox_coordinator() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (2, 2);&lt;br/&gt;&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    let signer1_id = frost::Identifier::try_from(1 as u16)?;&lt;br/&gt;    let key_package1: frost::keys::KeyPackage = shares[&amp;amp;signer1_id].clone().try_into()?;&lt;br/&gt;    let signer2_id = frost::Identifier::try_from(2 as u16)?;&lt;br/&gt;    let key_package2: frost::keys::KeyPackage = shares[&amp;amp;signer2_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    let message = b&amp;#34;BIP-64MOD: Anchor Data Proposal v1&amp;#34;;&lt;br/&gt;&lt;br/&gt;    let (nonces1, comms1) = frost::round1::commit(key_package1.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    let (nonces2, comms2) = frost::round1::commit(key_package2.signing_share(), &amp;amp;mut rng);&lt;br/&gt;&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    session_commitments.insert(signer1_id, comms1);&lt;br/&gt;    session_commitments.insert(signer2_id, comms2);&lt;br/&gt;&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments.clone(), message);&lt;br/&gt;&lt;br/&gt;    let share1 = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces1, &amp;amp;key_package1)?;&lt;br/&gt;    let share1_hex = hex::encode(share1.serialize());&lt;br/&gt;&lt;br/&gt;    let share2 = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces2, &amp;amp;key_package2)?;&lt;br/&gt;    let share2_hex = hex::encode(share2.serialize());&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Coordinator listening for Nostr events (simulated)...&amp;#34;);&lt;br/&gt;&lt;br/&gt;    process_relay_share(&amp;amp;share1_hex, 1_u16, &amp;amp;signing_package, &amp;amp;pubkey_package)?;&lt;br/&gt;    process_relay_share(&amp;amp;share2_hex, 2_u16, &amp;amp;signing_package, &amp;amp;pubkey_package)?;&lt;br/&gt;    println!(&amp;#34;All required shares processed. Coordinator would now aggregate.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Simulates a Signer producing a FROST signature share and preparing a Nostr event&lt;br/&gt;/// to be sent to a coordinator via a &amp;#34;mailbox&amp;#34; relay.&lt;br/&gt;///&lt;br/&gt;/// In a real ROAST setup, signers would generate their share and post it&lt;br/&gt;/// encrypted (e.g., using NIP-44) to a coordinator&amp;#39;s &amp;#34;mailbox&amp;#34; on a Nostr relay.&lt;br/&gt;/// This function demonstrates the creation of the signature share and the&lt;br/&gt;/// construction of a *simplified* Nostr event JSON.&lt;br/&gt;///&lt;br/&gt;/// # Arguments&lt;br/&gt;///&lt;br/&gt;/// * `_identifier` - The FROST identifier of the signer. (Currently unused in this specific function body).&lt;br/&gt;/// * `signing_package` - The FROST signing package received from the coordinator.&lt;br/&gt;/// * `nonces` - The signer&amp;#39;s nonces generated in Round 1.&lt;br/&gt;/// * `key_package` - The signer&amp;#39;s FROST key package.&lt;br/&gt;/// * `coordinator_pubkey` - The hex-encoded public key of the ROAST coordinator,&lt;br/&gt;///                          used to tag the Nostr event.&lt;br/&gt;///&lt;br/&gt;/// # Returns&lt;br/&gt;///&lt;br/&gt;/// A `Result` containing the JSON string of the Nostr event if successful,&lt;br/&gt;/// or a `Box&amp;lt;dyn std::error::Error&amp;gt;` if an error occurs.&lt;br/&gt;pub fn create_signer_event(&lt;br/&gt;    _identifier: frost::Identifier,&lt;br/&gt;    signing_package: &amp;amp;frost::SigningPackage,&lt;br/&gt;    nonces: &amp;amp;frost::round1::SigningNonces,&lt;br/&gt;    key_package: &amp;amp;frost::keys::KeyPackage,&lt;br/&gt;    coordinator_pubkey: &amp;amp;str, // The Hex pubkey of the ROAST coordinator&lt;br/&gt;) -&amp;gt; Result&amp;lt;String, Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;&lt;br/&gt;    // 1. Generate the partial signature share (Round 2 of FROST)&lt;br/&gt;    // This share is the core cryptographic output from the signer.&lt;br/&gt;    let share = frost::round2::sign(signing_package, nonces, key_package)?;&lt;br/&gt;    let share_bytes = share.serialize();&lt;br/&gt;    let share_hex = hex::encode(share_bytes);&lt;br/&gt;&lt;br/&gt;    // 2. Create a Session ID to tag the event&lt;br/&gt;    // This ID is derived from the signing package hash, allowing the coordinator&lt;br/&gt;    // to correlate shares belonging to the same signing session.&lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(signing_package.serialize()?);&lt;br/&gt;    let session_id = hex::encode(hasher.finalize());&lt;br/&gt;&lt;br/&gt;    // 3. Construct the Nostr Event JSON (Simplified)&lt;br/&gt;    // This JSON represents the event that a signer would post to a relay.&lt;br/&gt;    // In a production ROAST system, the &amp;#39;content&amp;#39; field (the signature share)&lt;br/&gt;    // would be encrypted for the coordinator using NIP-44.&lt;br/&gt;    let event = serde_json::json!({&lt;br/&gt;        &amp;#34;kind&amp;#34;: 4, // Example: Using Kind 4 (Private Message), though custom Kinds could be used for Sovereign Stack.&lt;br/&gt;        &amp;#34;pubkey&amp;#34;: hex::encode(key_package.verifying_key().serialize()?.as_slice()), // Signer&amp;#39;s public key&lt;br/&gt;        &amp;#34;created_at&amp;#34;: 1712050000, // Example timestamp&lt;br/&gt;        &amp;#34;tags&amp;#34;: [&lt;br/&gt;            [&amp;#34;p&amp;#34;, coordinator_pubkey],       // &amp;#39;p&amp;#39; tag: Directs the event to the coordinator.&lt;br/&gt;            [&amp;#34;i&amp;#34;, session_id],               // &amp;#39;i&amp;#39; tag: Provides a session identifier for filtering/requests.&lt;br/&gt;            [&amp;#34;t&amp;#34;, &amp;#34;frost-signature-share&amp;#34;]   // &amp;#39;t&amp;#39; tag: A searchable label for the event type.&lt;br/&gt;        ],&lt;br/&gt;        &amp;#34;content&amp;#34;: share_hex, // The actual signature share (would be encrypted in production).&lt;br/&gt;        &amp;#34;id&amp;#34;: &amp;#34;...&amp;#34;, // Event ID (filled by relay upon publishing)&lt;br/&gt;        &amp;#34;sig&amp;#34;: &amp;#34;...&amp;#34; // Event signature (filled by relay upon publishing)&lt;br/&gt;    });&lt;br/&gt;&lt;br/&gt;    Ok(event.to_string())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;pub fn simulate_frost_mailbox_post_signer() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    use rand::thread_rng;&lt;br/&gt;    use std::collections::BTreeMap;&lt;br/&gt;    use frost_secp256k1_tr as frost;&lt;br/&gt;&lt;br/&gt;    // This example simulates a single signer&amp;#39;s role in a ROAST mailbox post workflow.&lt;br/&gt;    // The general workflow is:&lt;br/&gt;    // 1. Coordinator sends a request for signatures (e.g., on a BIP-64MOD proposal).&lt;br/&gt;    // 2. Signers receive the proposal, perform local verification.&lt;br/&gt;    // 3. Each signer generates their signature share and posts it (encrypted) to a&lt;br/&gt;    //    Nostr relay, targeting the coordinator&amp;#39;s mailbox.&lt;br/&gt;    // 4. The coordinator collects enough shares to aggregate the final signature.&lt;br/&gt;&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    // For this example, we simulate a 2-of-2 threshold for simplicity.&lt;br/&gt;    let (max_signers, min_signers) = (2, 2);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 1. Key Generation (Simulated Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // In a real distributed setup, this would be DKG. Here, a &amp;#34;trusted dealer&amp;#34;&lt;br/&gt;    // generates the shares and public key package.&lt;br/&gt;    let (shares, _pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // For a 2-of-2 scheme, we have two signers. Let&amp;#39;s pick signer 1.&lt;br/&gt;    let signer1_id = frost::Identifier::try_from(1 as u16)?;&lt;br/&gt;    let key_package1: frost::keys::KeyPackage = shares[&amp;amp;signer1_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    let signer2_id = frost::Identifier::try_from(2 as u16)?;&lt;br/&gt;    let key_package2: frost::keys::KeyPackage = shares[&amp;amp;signer2_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    // The message that is to be signed (e.g., a hash of a Git commit or a Nostr event ID).&lt;br/&gt;    let message = b&amp;#34;This is a test message for ROAST mailbox post.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 2. Round 1: Commitment Phase (Signer&amp;#39;s role)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Each signer generates nonces and commitments.&lt;br/&gt;    let (nonces1, comms1) = frost::round1::commit(key_package1.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    let (nonces2, comms2) = frost::round1::commit(key_package2.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    &lt;br/&gt;    // The coordinator collects these commitments. Here, we simulate by putting them in a BTreeMap.&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    session_commitments.insert(signer1_id, comms1);&lt;br/&gt;    session_commitments.insert(signer2_id, comms2);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 3. Signing Package Creation (Coordinator&amp;#39;s role, simulated for context)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // The coordinator combines the collected commitments and the message to be signed&lt;br/&gt;    // into a signing package, which is then sent back to the signers.&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments, message);&lt;br/&gt;&lt;br/&gt;    // Dummy coordinator public key. In a real scenario, this would be the&lt;br/&gt;    // actual public key of the ROAST coordinator, used for event tagging&lt;br/&gt;    // and encryption (NIP-44).&lt;br/&gt;    let coordinator_pubkey_hex = &amp;#34;0000000000000000000000000000000000000000000000000000000000000001&amp;#34;;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 4. Create the Signer Event (Signer&amp;#39;s role)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // We demonstrate for signer 1. Signer 2 would perform a similar action.&lt;br/&gt;    let event_json_signer1 = create_signer_event(&lt;br/&gt;        signer1_id,&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;nonces1,&lt;br/&gt;        &amp;amp;key_package1,&lt;br/&gt;        coordinator_pubkey_hex,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Generated Nostr Event for Signer 1 Mailbox Post:&lt;br/&gt;{}&amp;#34;, event_json_signer1);&lt;br/&gt;&lt;br/&gt;    // Similarly, Signer 2 would generate their event:&lt;br/&gt;    let event_json_signer2 = create_signer_event(&lt;br/&gt;        signer2_id,&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;nonces2,&lt;br/&gt;        &amp;amp;key_package2,&lt;br/&gt;        coordinator_pubkey_hex,&lt;br/&gt;    )?;&lt;br/&gt;    println!(&amp;#34;Generated Nostr Event for Signer 2 Mailbox Post:&lt;br/&gt;{}&amp;#34;, event_json_signer2);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}
    </content>
    <updated>2026-04-04T01:40:37Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs9unyuz53j4dxmzxxr6tnz8r9n5vkjhwzxvv59jw7v42yqty4ptsgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj4kyrjq</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs9unyuz53j4dxmzxxr6tnz8r9n5vkjhwzxvv59jw7v42yqty4ptsgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj4kyrjq" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use get_file_hash_core::{get_relay_urls, publish_issue, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event, publish_patch_event};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-gnostr-repository-issue-example&amp;#34;; // Repository identifier&lt;br/&gt;    let issue_id_1 = &amp;#34;issue-001&amp;#34;; // Unique identifier for the first issue&lt;br/&gt;    let issue_id_2 = &amp;#34;issue-002&amp;#34;; // Unique identifier for the second issue&lt;br/&gt;    let title_1 = &amp;#34;Bug: Application crashes on startup&amp;#34;;&lt;br/&gt;    let content_1 = &amp;#34;The application fails to launch on macOS Ventura. It throws a &amp;#39;Segmentation Fault&amp;#39; error immediately after execution. This was observed on version `v1.2.3`.&lt;br/&gt;&lt;br/&gt;Steps to reproduce:&lt;br/&gt;1. Download `app-v1.2.3-macos.tar.gz`&lt;br/&gt;2. Extract the archive&lt;br/&gt;3. Run `./app`&lt;br/&gt;&lt;br/&gt;Expected behavior: Application launches successfully.&lt;br/&gt;Actual behavior: Application crashes with &amp;#39;Segmentation Fault&amp;#39;.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    let title_2 = &amp;#34;Feature Request: Dark Mode&amp;#34;;&lt;br/&gt;    let content_2 = &amp;#34;Users have requested a dark mode option to improve readability and reduce eye strain during prolonged use. This should be toggleable in the settings menu.&lt;br/&gt;&lt;br/&gt;Considerations:&lt;br/&gt;- Adherence to system dark mode settings.&lt;br/&gt;- Consistent styling across all UI components.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Publish an issue without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing issue &amp;#39;{}&amp;#39; without build_manifest_event_id...&amp;#34;, title_1);&lt;br/&gt;    publish_issue!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        issue_id_1,&lt;br/&gt;        title_1,&lt;br/&gt;        content_1&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Issue &amp;#39;{}&amp;#39; published.&amp;#34;, title_1);&lt;br/&gt;&lt;br/&gt;    // Example 2: Publish an issue with build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing issue &amp;#39;{}&amp;#39; with build_manifest_event_id...&amp;#34;, title_2);&lt;br/&gt;    publish_issue!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        issue_id_2,&lt;br/&gt;        title_2,&lt;br/&gt;        content_2,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Issue &amp;#39;{}&amp;#39; published.&amp;#34;, title_2);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_issue --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:36Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsxd9k5hd2upzj54y7thtrtq9r6cl8k3usdcnppulmaf4p9q5502jqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj942cs0</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsxd9k5hd2upzj54y7thtrtq9r6cl8k3usdcnppulmaf4p9q5502jqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj942cs0" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let max_signers = 3;&lt;br/&gt;    let min_signers = 2;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 0: Key Generation (Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    // In a real P2P setup, you&amp;#39;d use Distributed Key Generation (DKG).&lt;br/&gt;    // For local testing/simulations, the trusted dealer is faster.&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verifying the public key exists&lt;br/&gt;    let group_public_key = pubkey_package.verifying_key();&lt;br/&gt;    println!(&amp;#34;Group Public Key: {:?}&amp;#34;, group_public_key);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 1: Commitment&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let message = b&amp;#34;BIP-64MOD Consensus Proposal&amp;#34;;&lt;br/&gt;    let mut signing_commitments = BTreeMap::new();&lt;br/&gt;    let mut participant_nonces = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    // Participants 1 and 2 decide to sign&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        &lt;br/&gt;        // Generate nonces and commitments&lt;br/&gt;        let (nonces, commitments) = frost::round1::commit(&lt;br/&gt;            shares[&amp;amp;identifier].signing_share(),&lt;br/&gt;            &amp;amp;mut rng,&lt;br/&gt;        );&lt;br/&gt;        &lt;br/&gt;        signing_commitments.insert(identifier, commitments);&lt;br/&gt;        participant_nonces.insert(identifier, nonces);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 2: Signing&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let mut signature_shares = BTreeMap::new();&lt;br/&gt;    let signing_package = frost::SigningPackage::new(signing_commitments, message);&lt;br/&gt;&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        let nonces = &amp;amp;participant_nonces[&amp;amp;identifier];&lt;br/&gt;        &lt;br/&gt;        // Each participant produces a signature share&lt;br/&gt;        let key_package: frost::keys::KeyPackage = shares[&amp;amp;identifier].clone().try_into()?;&lt;br/&gt;        let share = frost::round2::sign(&amp;amp;signing_package, nonces, &amp;amp;key_package)?;&lt;br/&gt;        signature_shares.insert(identifier, share);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Finalization: Aggregation&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let group_signature = frost::aggregate(&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;signature_shares,&lt;br/&gt;        &amp;amp;pubkey_package,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verification&lt;br/&gt;    group_public_key.verify(message, &amp;amp;group_signature)?;&lt;br/&gt;    &lt;br/&gt;    println!(&amp;#34;Threshold signature verified successfully!&amp;#34;);&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example trusted-dealer --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:35Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsx7sdfk8fmlrlpf38ewne6th6rtx5sz8qc4l6fq5tl02w9jjksp3gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjjg29at</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsx7sdfk8fmlrlpf38ewne6th6rtx5sz8qc4l6fq5tl02w9jjksp3gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjjg29at" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:25Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsz68pdm0a9f5u2fqve5amxdmftu64k52jn55rks5k7ug0l899mgagzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjxtat8q</id>
    
      <title type="html">#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))] ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsz68pdm0a9f5u2fqve5amxdmftu64k52jn55rks5k7ug0l899mgagzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjxtat8q" />
    <content type="html">
      #[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use std::fs;&lt;br/&gt;    use std::path::PathBuf;&lt;br/&gt;&lt;br/&gt;    let manifest_dir = PathBuf::from(std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap());&lt;br/&gt;    let crate_src_path = manifest_dir.join(&amp;#34;src&amp;#34;).join(&amp;#34;online_relays_gps.csv&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Only download if the file doesn&amp;#39;t exist or is empty&lt;br/&gt;    if !crate_src_path.exists() || fs::metadata(&amp;amp;crate_src_path).map(|m| m.len() == 0).unwrap_or(true) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Downloading online_relays_gps.csv...&amp;#34;);&lt;br/&gt;        let url = &amp;#34;&lt;a href=&#34;https://raw.githubusercontent.com/permissionlesstech/bitchat/main/relays/online_relays_gps.csv&amp;#34&#34;&gt;https://raw.githubusercontent.com/permissionlesstech/bitchat/main/relays/online_relays_gps.csv&amp;#34&lt;/a&gt;;;&lt;br/&gt;        match reqwest::get(url).await {&lt;br/&gt;            Ok(response) =&amp;gt; {&lt;br/&gt;                if response.status().is_success() {&lt;br/&gt;                    match response.text().await {&lt;br/&gt;                        Ok(content) =&amp;gt; {&lt;br/&gt;                            fs::write(&amp;amp;crate_src_path, content).expect(&amp;#34;Unable to write online_relays_gps.csv&amp;#34;);&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Successfully downloaded online_relays_gps.csv to {:?}&amp;#34;, crate_src_path);&lt;br/&gt;                        },&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to get text from response: {}&amp;#34;, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                } else {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to download online_relays_gps.csv: HTTP status {}&amp;#34;, response.status());&lt;br/&gt;                }&lt;br/&gt;            },&lt;br/&gt;            Err(e) =&amp;gt; {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to fetch online_relays_gps.csv: {}&amp;#34;, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;)))]&lt;br/&gt;fn main() {&lt;br/&gt;    // Placeholder for when the nostr feature is not enabled or in debug mode&lt;br/&gt;    println!(&amp;#34;cargo:warning=Skipping online_relays_gps.csv download (nostr feature not enabled or debug mode)&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:25Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsps6n0x8adu9sr2qhrwck5seuphx6n0y7vgc3h6ymk38jurysrrhszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjlj7f0f</id>
    
      <title type="html">/// deterministic nostr event build example // deterministic ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsps6n0x8adu9sr2qhrwck5seuphx6n0y7vgc3h6ymk38jurysrrhszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjlj7f0f" />
    <content type="html">
      /// deterministic nostr event build example&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use get_file_hash_core::{get_git_tracked_files, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use nostr_sdk::{EventBuilder, Keys, Tag, SecretKey};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use std::fs;&lt;br/&gt;&lt;br/&gt;use std::path::PathBuf;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use ::hex;&lt;br/&gt;&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    let manifest_dir = std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap();&lt;br/&gt;    let is_git_repo = std::path::Path::new(&amp;amp;manifest_dir).join(&amp;#34;.git&amp;#34;).exists();&lt;br/&gt;    #[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;	#[allow(unused_mut)]&lt;br/&gt;    let mut git_branch_str = String::new();&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_NAME={}&amp;#34;, env!(&amp;#34;CARGO_PKG_NAME&amp;#34;));&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_VERSION={}&amp;#34;, env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;));&lt;br/&gt;&lt;br/&gt;    if is_git_repo {&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;&lt;br/&gt;        let git_branch_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;--abbrev-ref&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for branch name&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_branch_str = if git_branch_output.status.success() &amp;amp;&amp;amp; !git_branch_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_branch_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git branch command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_branch_output.status, String::from_utf8_lossy(&amp;amp;git_branch_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH={}&amp;#34;, git_branch_str);&lt;br/&gt;    } else {&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH=&amp;#34;);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH=&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=.git/HEAD&amp;#34;);&lt;br/&gt;&lt;br/&gt;    //#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    //let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;    let cargo_toml_hash = get_file_hash!(&amp;#34;../Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_TOML_HASH={}&amp;#34;, cargo_toml_hash);&lt;br/&gt;&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;../src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=LIB_HASH={}&amp;#34;, lib_hash);&lt;br/&gt;&lt;br/&gt;    let build_hash = get_file_hash!(&amp;#34;../build.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=BUILD_HASH={}&amp;#34;, build_hash);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=build.rs&amp;#34;);&lt;br/&gt;    let online_relays_csv_path = PathBuf::from(&amp;amp;manifest_dir).join(&amp;#34;src/get_file_hash_core/src/online_relays_gps.csv&amp;#34;);&lt;br/&gt;    if online_relays_csv_path.exists() {&lt;br/&gt;        println!(&amp;#34;cargo:rerun-if-changed={}&amp;#34;, online_relays_csv_path.to_str().unwrap());&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    if cfg!(not(debug_assertions)) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Nostr feature enabled: Build may take longer due to network operations (publishing events to relays).&amp;#34;);&lt;br/&gt;&lt;br/&gt;        // This code only runs in release builds&lt;br/&gt;        let package_version = std::env::var(&amp;#34;CARGO_PKG_VERSION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;        let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;        if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        let files_to_publish: Vec&amp;lt;String&amp;gt; = get_git_tracked_files(&amp;amp;PathBuf::from(&amp;amp;manifest_dir));&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;        // Create padded_commit_hash&lt;br/&gt;        let padded_commit_hash = format!(&amp;#34;{:0&amp;gt;64}&amp;#34;, &amp;amp;git_commit_hash_str);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=PADDED_COMMIT_HASH={}&amp;#34;, padded_commit_hash);&lt;br/&gt;        // Initialize client and keys once&lt;br/&gt;        let initial_secret_key = SecretKey::parse(&amp;amp;padded_commit_hash).expect(&amp;#34;Failed to create Nostr SecretKey from PADDED_COMMIT_HASH&amp;#34;);&lt;br/&gt;        let initial_keys = Keys::new(initial_secret_key);&lt;br/&gt;        let mut client = nostr_sdk::Client::new(initial_keys.clone());&lt;br/&gt;        let mut relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;        // Add relays to the client&lt;br/&gt;        for relay_url in relay_urls.iter() {&lt;br/&gt;            if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to add relay {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        client.connect().await;&lt;br/&gt;        println!(&amp;#34;cargo:warning=Added and connected to {} relays.&amp;#34;, relay_urls.len());&lt;br/&gt;&lt;br/&gt;        let mut published_event_ids: Vec&amp;lt;Tag&amp;gt; = Vec::new();&lt;br/&gt;        let mut total_bytes_sent: usize = 0;&lt;br/&gt;    &lt;br/&gt;        for file_path_str in &amp;amp;files_to_publish {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Processing file: {}&amp;#34;, file_path_str);&lt;br/&gt;            match fs::read(file_path_str) {&lt;br/&gt;                Ok(bytes) =&amp;gt; {&lt;br/&gt;                    let mut hasher = Sha256::new();&lt;br/&gt;                    hasher.update(&amp;amp;bytes);&lt;br/&gt;                    let result = hasher.finalize();&lt;br/&gt;                    let file_hash_hex = hex::encode(result);&lt;br/&gt;&lt;br/&gt;                    match SecretKey::from_hex(&amp;amp;file_hash_hex.clone()) {&lt;br/&gt;                        Ok(secret_key) =&amp;gt; {&lt;br/&gt;                            let keys = Keys::new(secret_key);&lt;br/&gt;                            let content = String::from_utf8_lossy(&amp;amp;bytes).into_owned();&lt;br/&gt;                            let tags = vec![&lt;br/&gt;                                Tag::parse([&amp;#34;file&amp;#34;, file_path_str].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                                Tag::parse([&amp;#34;version&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                            ];&lt;br/&gt;                            let event_builder = EventBuilder::text_note(content).tags(tags);&lt;br/&gt;&lt;br/&gt;                            if let Some(event_id) = publish_nostr_event_if_release(&amp;amp;mut client, file_hash_hex, keys.clone(), event_builder, &amp;amp;mut relay_urls, file_path_str, &amp;amp;output_dir, &amp;amp;mut total_bytes_sent).await {&lt;br/&gt;                                published_event_ids.push(Tag::event(event_id));&lt;br/&gt;                            }&lt;br/&gt;&lt;br/&gt;                            // Publish metadata event&lt;br/&gt;                            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                                &amp;amp;keys,&lt;br/&gt;                                &amp;amp;relay_urls,&lt;br/&gt;                                DEFAULT_PICTURE_URL,&lt;br/&gt;                                DEFAULT_BANNER_URL,&lt;br/&gt;                                file_path_str,&lt;br/&gt;                            ).await;&lt;br/&gt;                        }&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to derive Nostr secret key for {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                }&lt;br/&gt;                Err(e) =&amp;gt; {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to read file {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        // Create and publish the build_manifest&lt;br/&gt;        if !published_event_ids.is_empty() {&lt;br/&gt;&lt;br/&gt;            //TODO this will be either the default or detected from env vars PRIVATE_KEY&lt;br/&gt;            let keys = Keys::new(SecretKey::from_hex(DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr keys from DEFAULT_GNOSTR_KEY&amp;#34;));&lt;br/&gt;            let cloned_keys = keys.clone();&lt;br/&gt;            let content = format!(&amp;#34;Build manifest for get_file_hash v{}&amp;#34;, package_version);&lt;br/&gt;            let mut tags = vec![&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;            ];&lt;br/&gt;            tags.extend(published_event_ids);&lt;br/&gt;&lt;br/&gt;            let event_builder = EventBuilder::text_note(content.clone()).tags(tags);&lt;br/&gt;&lt;br/&gt;            if let Some(event_id) = publish_nostr_event_if_release(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                hex::encode(Sha256::digest(content.as_bytes())),&lt;br/&gt;                keys,&lt;br/&gt;                event_builder,&lt;br/&gt;                &amp;amp;mut relay_urls,&lt;br/&gt;                &amp;#34;build_manifest.json&amp;#34;,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;mut total_bytes_sent,&lt;br/&gt;            ).await {&lt;br/&gt;&lt;br/&gt;                let build_manifest_event_id = Some(event_id);&lt;br/&gt;&lt;br/&gt;            // Publish metadata event for the build manifest&lt;br/&gt;            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                &amp;amp;cloned_keys, // Use reference to cloned keys here&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                DEFAULT_PICTURE_URL,&lt;br/&gt;                DEFAULT_BANNER_URL,&lt;br/&gt;                &amp;amp;format!(&amp;#34;build_manifest:{}&amp;#34;, package_version),&lt;br/&gt;            ).await;&lt;br/&gt;            let git_commit_hash = &amp;amp;git_commit_hash_str;&lt;br/&gt;            let git_branch = &amp;amp;git_branch_str;&lt;br/&gt;            let repo_url = std::env::var(&amp;#34;CARGO_PKG_REPOSITORY&amp;#34;).unwrap();&lt;br/&gt;            let repo_name = std::env::var(&amp;#34;CARGO_PKG_NAME&amp;#34;).unwrap();&lt;br/&gt;            let repo_description = std::env::var(&amp;#34;CARGO_PKG_DESCRIPTION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;            let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;            if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            let announcement_keys = Keys::new(SecretKey::from_hex(build_manifest_event_id.unwrap().to_hex().as_str()).expect(&amp;#34;Failed to create Nostr keys from build_manifest_event_id&amp;#34;));&lt;br/&gt;            let announcement_pubkey_hex = announcement_keys.public_key().to_string();&lt;br/&gt;&lt;br/&gt;            // Publish NIP-34 Repository Announcement&lt;br/&gt;            if let Some(_event_id) = get_repo_announcement_event(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                &amp;amp;announcement_keys,&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                &amp;amp;repo_url,&lt;br/&gt;                &amp;amp;repo_name,&lt;br/&gt;                &amp;amp;repo_description,&lt;br/&gt;                &amp;amp;git_commit_hash,&lt;br/&gt;                &amp;amp;git_branch,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;announcement_pubkey_hex&lt;br/&gt;            ).await {&lt;br/&gt;                // Successfully published announcement&lt;br/&gt;            }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        println!(&amp;#34;cargo:warning=Total bytes sent to Nostr relays: {} bytes ({} MB)&amp;#34;, total_bytes_sent, total_bytes_sent as f64 / 1024.0 / 1024.0);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:25Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsrn6tne7k6gkgxvvqe305m0mf8kkdnjc95r484faavh3rlenqqafqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjak3kdj</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsrn6tne7k6gkgxvvqe305m0mf8kkdnjc95r484faavh3rlenqqafqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjak3kdj" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;/// A simplified ROAST Coordinator that manages signing sessions&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;struct RoastCoordinator {&lt;br/&gt;    min_signers: u16,&lt;br/&gt;    _message: Vec&amp;lt;u8&amp;gt;,&lt;br/&gt;    commitments: BTreeMap&amp;lt;frost::Identifier, frost::round1::SigningCommitments&amp;gt;,&lt;br/&gt;    nonces: BTreeMap&amp;lt;frost::Identifier, frost::round1::SigningNonces&amp;gt;,&lt;br/&gt;    shares: BTreeMap&amp;lt;frost::Identifier, frost::round2::SignatureShare&amp;gt;,&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;impl RoastCoordinator {&lt;br/&gt;    fn new(min_signers: u16, message: &amp;amp;[u8]) -&amp;gt; Self {&lt;br/&gt;        Self {&lt;br/&gt;            min_signers,&lt;br/&gt;            _message: message.to_vec(),&lt;br/&gt;            commitments: BTreeMap::new(),&lt;br/&gt;            nonces: BTreeMap::new(),&lt;br/&gt;            shares: BTreeMap::new(),&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// ROAST Logic: Collect commitments until we hit the threshold.&lt;br/&gt;    /// In a real P2P system, this would be an async stream handler.&lt;br/&gt;    fn add_commitment(&amp;amp;mut self, id: frost::Identifier, comms: frost::round1::SigningCommitments, nonces: frost::round1::SigningNonces) {&lt;br/&gt;        if self.commitments.len() &amp;lt; self.min_signers as usize {&lt;br/&gt;            self.commitments.insert(id, comms);&lt;br/&gt;            self.nonces.insert(id, nonces);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// ROAST Logic: Collect signature shares.&lt;br/&gt;    fn add_share(&amp;amp;mut self, id: frost::Identifier, share: frost::round2::SignatureShare) {&lt;br/&gt;        if self.shares.len() &amp;lt; self.min_signers as usize {&lt;br/&gt;            self.shares.insert(id, share);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    fn is_ready_to_sign(&amp;amp;self) -&amp;gt; bool {&lt;br/&gt;        self.commitments.len() &amp;gt;= self.min_signers as usize&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    fn is_ready_to_aggregate(&amp;amp;self) -&amp;gt; bool {&lt;br/&gt;        self.shares.len() &amp;gt;= self.min_signers as usize&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (5, 3);&lt;br/&gt;    let message = b&amp;#34;BIP-64MOD Context: ROAST Coordination&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // 1. Setup: Generate keys (Dealer mode for simulation)&lt;br/&gt;    let (key_shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    let mut coordinator = RoastCoordinator::new(min_signers, message);&lt;br/&gt;&lt;br/&gt;    // 2. Round 1: Asynchronous Commitment Collection&lt;br/&gt;    // Simulate signers 1, 3, and 5 responding first (ROAST skips 2 and 4)&lt;br/&gt;    for &amp;amp;id_num in &amp;amp;[1, 3, 5] {&lt;br/&gt;        let id = frost::Identifier::try_from(id_num as u16)?;&lt;br/&gt;        let (nonces, comms) = frost::round1::commit(key_shares[&amp;amp;id].signing_share(), &amp;amp;mut rng);&lt;br/&gt;        &lt;br/&gt;        // Signers store their nonces locally, send comms to coordinator&lt;br/&gt;        coordinator.add_commitment(id, comms, nonces);&lt;br/&gt;        &lt;br/&gt;        // Note: Signer 2 was &amp;#34;offline&amp;#34;, but ROAST doesn&amp;#39;t care because we hit 3/5.&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 3. Round 2: Signing&lt;br/&gt;    if coordinator.is_ready_to_sign() {&lt;br/&gt;        let signing_package = frost::SigningPackage::new(coordinator.commitments.clone(), message);&lt;br/&gt;        &lt;br/&gt;        let mut temp_shares = BTreeMap::new();&lt;br/&gt;        for &amp;amp;id in coordinator.commitments.keys() {&lt;br/&gt;            // In reality, coordinator sends signing_package to signers&lt;br/&gt;            // Here we simulate the signers producing shares&lt;br/&gt;&lt;br/&gt;            let nonces = &amp;amp;coordinator.nonces[&amp;amp;id];&lt;br/&gt;            &lt;br/&gt;            let key_package: frost::keys::KeyPackage = key_shares[&amp;amp;id].clone().try_into()?;&lt;br/&gt;            let share = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces, &amp;amp;key_package)?;&lt;br/&gt;            temp_shares.insert(id, share);&lt;br/&gt;        }&lt;br/&gt;        for (id, share) in temp_shares {&lt;br/&gt;            coordinator.add_share(id, share);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 4. Finalization: Aggregation&lt;br/&gt;    if coordinator.is_ready_to_aggregate() {&lt;br/&gt;        let signing_package = frost::SigningPackage::new(coordinator.commitments.clone(), message);&lt;br/&gt;        let group_signature = frost::aggregate(&lt;br/&gt;            &amp;amp;signing_package,&lt;br/&gt;            &amp;amp;coordinator.shares,&lt;br/&gt;            &amp;amp;pubkey_package,&lt;br/&gt;        )?;&lt;br/&gt;&lt;br/&gt;        pubkey_package.verifying_key().verify(message, &amp;amp;group_signature)?;&lt;br/&gt;        println!(&amp;#34;ROAST-coordinated signature verified!&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example roast-experiment --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:20Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsv9pv8j8fxysezxh7kj70u4w6nh8fd7c2v3qa29cm7w4g75dx4pagzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjh6zhhk</id>
    
      <title type="html">[package] name = &amp;#34;get_file_hash_core&amp;#34; version = { ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsv9pv8j8fxysezxh7kj70u4w6nh8fd7c2v3qa29cm7w4g75dx4pagzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjh6zhhk" />
    <content type="html">
      [package]&lt;br/&gt;name = &amp;#34;get_file_hash_core&amp;#34;&lt;br/&gt;version = { workspace = true }&lt;br/&gt;edition = { workspace = true }&lt;br/&gt;description = { workspace = true }&lt;br/&gt;license = { workspace = true }&lt;br/&gt;documentation = { workspace = true }&lt;br/&gt;homepage = { workspace = true }&lt;br/&gt;repository = { workspace = true }&lt;br/&gt;authors = { workspace = true }&lt;br/&gt;&lt;br/&gt;[features]&lt;br/&gt;nostr = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:serde_json&amp;#34;, &amp;#34;dep:sha2&amp;#34;, &amp;#34;dep:hex&amp;#34;, &amp;#34;dep:reqwest&amp;#34;, &amp;#34;dep:tokio&amp;#34;, &amp;#34;dep:csv&amp;#34;, &amp;#34;dep:url&amp;#34;, &amp;#34;dep:frost-secp256k1-tr&amp;#34;, &amp;#34;dep:rand&amp;#34;]&lt;br/&gt;frost = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:serde_json&amp;#34;, &amp;#34;dep:sha2&amp;#34;, &amp;#34;dep:hex&amp;#34;, &amp;#34;dep:reqwest&amp;#34;, &amp;#34;dep:tokio&amp;#34;, &amp;#34;dep:csv&amp;#34;, &amp;#34;dep:url&amp;#34;, &amp;#34;dep:frost-secp256k1-tr&amp;#34;, &amp;#34;dep:rand&amp;#34;]&lt;br/&gt;&lt;br/&gt;[dependencies]&lt;br/&gt;sha2 = { workspace = true, optional = true }&lt;br/&gt;nostr = { workspace = true, optional = true }&lt;br/&gt;serde_json = { workspace = true, optional = true }&lt;br/&gt;nostr-sdk = { workspace = true, optional = true }&lt;br/&gt;hex = { workspace = true, optional = true }&lt;br/&gt;csv = { workspace = true, optional = true }&lt;br/&gt;url = { workspace = true, optional = true }&lt;br/&gt;frost-secp256k1-tr = { workspace = true, optional = true }&lt;br/&gt;rand = { workspace = true, optional = true }&lt;br/&gt;&lt;br/&gt;[dev-dependencies]&lt;br/&gt;sha2 = { workspace = true }&lt;br/&gt;tempfile = { workspace = true }&lt;br/&gt;nostr = { workspace = true }&lt;br/&gt;nostr-sdk = { workspace = true }&lt;br/&gt;serde_json = { workspace = true }&lt;br/&gt;hex = { workspace = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;macros&amp;#34;, &amp;#34;rt-multi-thread&amp;#34;] }&lt;br/&gt;csv = { workspace = true }&lt;br/&gt;url = { workspace = true }&lt;br/&gt;frost-secp256k1-tr = { workspace = true }&lt;br/&gt;serial_test = { workspace = true, features = [&amp;#34;test_logging&amp;#34;] }&lt;br/&gt;log = { workspace = true }&lt;br/&gt;&lt;br/&gt;[build-dependencies]&lt;br/&gt;reqwest = { workspace = true, features = [&amp;#34;json&amp;#34;], optional = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;macros&amp;#34;, &amp;#34;rt-multi-thread&amp;#34;], optional = true }&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:13Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsgcdqryq8jutzjz8vfjxnypuyfxu0x0suwppkmxwvm7lseqa3545czyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjmtjvrp</id>
    
      <title type="html">/// BIP-64MOD &#43; GCC: Complete Git Empty &amp;amp; Genesis Constants ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsgcdqryq8jutzjz8vfjxnypuyfxu0x0suwppkmxwvm7lseqa3545czyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjmtjvrp" />
    <content type="html">
      /// BIP-64MOD &#43; GCC: Complete Git Empty &amp;amp; Genesis Constants&lt;br/&gt;/// &lt;br/&gt;/// This module provides the standard cryptographic identifiers for &amp;#34;null&amp;#34;, &lt;br/&gt;/// &amp;#34;empty&amp;#34;, and &amp;#34;genesis&amp;#34; states, including NIP-19 (Bech32) identities.&lt;br/&gt;pub struct GitEmptyState;&lt;br/&gt;&lt;br/&gt;impl GitEmptyState {&lt;br/&gt;    // === NULL REFERENCE (Zero Hash) ===&lt;br/&gt;    pub const NULL_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;0000000000000000000000000000000000000000000000000000000000000000&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // === EMPTY BLOB (Empty File) ===&lt;br/&gt;    pub const BLOB_SHA1: &amp;amp;&amp;#39;static str = &amp;#34;e69de29bb2d1d6434b8b29ae775ad8c2e48c5391&amp;#34;;&lt;br/&gt;    pub const BLOB_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813&amp;#34;;&lt;br/&gt;    pub const BLOB_NSEC: &amp;amp;&amp;#39;static str = &amp;#34;nsec1guaq7npmaz5ndqdzvl3mr6d8mndprp2rdls5ram5jys2xqmjrqfsdzhrp6&amp;#34;;&lt;br/&gt;    pub const BLOB_NPUB: &amp;amp;&amp;#39;static str = &amp;#34;npub180cvv07tjdrghvkyh6964p7w9vsqpf3p05868v399v86p8y6f69sq5fdp0&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // === EMPTY TREE (Empty Directory) ===&lt;br/&gt;    pub const TREE_SHA1: &amp;amp;&amp;#39;static str = &amp;#34;4b825dc642cb6eb9a060e54bf8d69288fbee4904&amp;#34;;&lt;br/&gt;    pub const TREE_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321&amp;#34;;&lt;br/&gt;    pub const TREE_NSEC: &amp;amp;&amp;#39;static str = &amp;#34;nsec1dmceksfzt3fknuwpqn29mrv9a75mq4a48v2tfwde88whfhkv2vsslsc46c&amp;#34;;&lt;br/&gt;    pub const TREE_NPUB: &amp;amp;&amp;#39;static str = &amp;#34;npub1pxmpep6yk7z6p332u9588k0vscg26rv29pynvscg26rv29pynvsq6erdfh&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // === GENESIS COMMIT (DeepSpaceM1 @ Epoch 0) ===&lt;br/&gt;    /// Result of: git commit --allow-empty -m &amp;#39;Initial commit&amp;#39; &lt;br/&gt;    /// With Author/Committer: DeepSpaceM1 &amp;lt;ds_m1@gnostr.org&amp;gt; @ 1970-01-01T00:00:00Z&lt;br/&gt;    pub const GENESIS_AUTHOR_NAME: &amp;amp;&amp;#39;static str = &amp;#34;DeepSpaceM1&amp;#34;;&lt;br/&gt;    pub const GENESIS_AUTHOR_EMAIL: &amp;amp;&amp;#39;static str = &amp;#34;ds_m1@gnostr.org&amp;#34;;&lt;br/&gt;    pub const GENESIS_DATE_UNIX: i64 = 0;&lt;br/&gt;    pub const GENESIS_MESSAGE: &amp;amp;&amp;#39;static str = &amp;#34;Initial commit&amp;#34;;&lt;br/&gt;&lt;br/&gt;    /// The resulting SHA-256 Commit Hash for this specific configuration&lt;br/&gt;    pub const GENESIS_COMMIT_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;e9768652d87e07663479a0ad402513f56d953930b659c2ef389d4d03d3623910&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    /// The NIP-19 Identity associated with the Genesis Commit&lt;br/&gt;    pub const GENESIS_NSEC: &amp;amp;&amp;#39;static str = &amp;#34;nsec1jpxmpep6yk7z6p332u9588k0vscg26rv29pynvscg26rv29pynvsq68at9d&amp;#34;;&lt;br/&gt;    pub const GENESIS_NPUB: &amp;amp;&amp;#39;static str = &amp;#34;npub1pxmpep6yk7z6p332u9588k0vscg26rv29pynvscg26rv29pynvsq6erdfh&amp;#34;;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Helper for constructing the commit object string for hashing&lt;br/&gt;pub mod builders {&lt;br/&gt;    use super::GitEmptyState;&lt;br/&gt;&lt;br/&gt;    pub fn build_genesis_commit_object() -&amp;gt; String {&lt;br/&gt;        format!(&lt;br/&gt;            &amp;#34;tree {}\nauthor {} &amp;lt;{}&amp;gt; {} &#43;0000\ncommitter {} &amp;lt;{}&amp;gt; {} &#43;0000\n\n{}\n&amp;#34;,&lt;br/&gt;            GitEmptyState::TREE_SHA256,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_NAME,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_EMAIL,&lt;br/&gt;            GitEmptyState::GENESIS_DATE_UNIX,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_NAME,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_EMAIL,&lt;br/&gt;            GitEmptyState::GENESIS_DATE_UNIX,&lt;br/&gt;            GitEmptyState::GENESIS_MESSAGE&lt;br/&gt;        )&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;--- BIP-64MOD &#43; GCC Genesis State ---&amp;#34;);&lt;br/&gt;    println!(&amp;#34;Commit Hash: {}&amp;#34;, GitEmptyState::GENESIS_COMMIT_SHA256);&lt;br/&gt;    println!(&amp;#34;Author:      {} &amp;lt;{}&amp;gt;&amp;#34;, GitEmptyState::GENESIS_AUTHOR_NAME, GitEmptyState::GENESIS_AUTHOR_EMAIL);&lt;br/&gt;    println!(&amp;#34;Timestamp:   {}&amp;#34;, GitEmptyState::GENESIS_DATE_UNIX);&lt;br/&gt;    println!(&amp;#34;NSEC:        {}&amp;#34;, GitEmptyState::GENESIS_NSEC);&lt;br/&gt;    &lt;br/&gt;    let object_raw = builders::build_genesis_commit_object();&lt;br/&gt;    println!(&amp;#34;\nRaw Git Commit Object:\n---\n{}---&amp;#34;, object_raw);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:05Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsfpeuglpppemr3veh2hz2klt3585fmd9wy9njssvtz63vqlzhghsqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj9p34eh</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsfpeuglpppemr3veh2hz2klt3585fmd9wy9njssvtz63vqlzhghsqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj9p34eh" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:04Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsylcfnh3ln8e6rre4xrajp2xt0xeq0zg0akksw6lkcmsyauptmmfszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjac98vh</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsylcfnh3ln8e6rre4xrajp2xt0xeq0zg0akksw6lkcmsyauptmmfszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjac98vh" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[allow(unused_imports)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::repository_announcement;&lt;br/&gt;    use get_file_hash_core::get_file_hash;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use sha2::{Digest, Sha256};&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let project_name = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let description = &amp;#34;A fantastic new project example.&amp;#34;;&lt;br/&gt;    let clone_url = &amp;#34;git@github.com:user/my-awesome-repo-example.git&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing repository announcement without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    repository_announcement!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        project_name,&lt;br/&gt;        description,&lt;br/&gt;        clone_url,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use a known file in your project&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository announcement without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing repository announcement with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    repository_announcement!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        project_name,&lt;br/&gt;        description,&lt;br/&gt;        clone_url,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use a known file in your project&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository announcement with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example repository_announcement --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:02Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsvavx9frs0elp9f0jptjwlzkq5g7zs6nnjdgj00lutcnn09fvwylczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj4z7kwg</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsvavx9frs0elp9f0jptjwlzkq5g7zs6nnjdgj00lutcnn09fvwylczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj4z7kwg" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;use get_file_hash::{BUILD_HASH, CARGO_TOML_HASH, LIB_HASH};&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART0: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use get_file_hash::CARGO_TOML_HASH;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let readme_hash = get_file_hash!(&amp;#34;src/bin/readme.rs&amp;#34;);&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, lib_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/bin/readme.rs is: {}&amp;#34;, readme_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of Cargo.toml is: {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r&amp;#34;## Release&lt;br/&gt;## [`README.md`](./README.md)&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin readme &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## [`src/bin/readme.rs`](src/bin/readme.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/readme.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`build.rs`](build.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `build.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART3: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`Cargo.toml`](Cargo.toml)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `Cargo.toml`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART4: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`src/lib.rs`](src/lib.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/lib.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART_NIP34: &amp;amp;str = r&amp;#34;## NIP-34 Integration: Git Repository Events on Nostr&lt;br/&gt;&lt;br/&gt;This library provides a set of powerful macros and functions for integrating Git repository events with the Nostr protocol, adhering to the [NIP-34: Git Repositories on Nostr](&lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/34.md&#34;&gt;https://github.com/nostr-protocol/nips/blob/master/34.md&lt;/a&gt;) specification.&lt;br/&gt;&lt;br/&gt;These tools allow you to publish various Git-related events to Nostr relays, enabling decentralized tracking and collaboration for your code repositories.&lt;br/&gt;&lt;br/&gt;### Available NIP-34 Macros&lt;br/&gt;&lt;br/&gt;Each macro provides a convenient way to publish specific NIP-34 event kinds:&lt;br/&gt;&lt;br/&gt;*   [`repository_announcement!`](#repository_announcement)&lt;br/&gt;    *   Publishes a `Repository Announcement` event (Kind 30617) to announce a new or updated Git repository.&lt;br/&gt;*   [`publish_patch!`](#publish_patch)&lt;br/&gt;    *   Publishes a `Patch` event (Kind 1617) containing a Git patch (diff) for a specific commit.&lt;br/&gt;*   [`publish_pull_request!`](#publish_pull_request)&lt;br/&gt;    *   Publishes a `Pull Request` event (Kind 1618) to propose changes and facilitate code review.&lt;br/&gt;*   [`publish_pr_update!`](#publish_pr_update)&lt;br/&gt;    *   Publishes a `Pull Request Update` event (Kind 1619) to update an existing pull request.&lt;br/&gt;*   [`publish_repository_state!`](#publish_repository_state)&lt;br/&gt;    *   Publishes a `Repository State` event (Kind 1620) to announce the current state of a branch (e.g., its latest commit).&lt;br/&gt;*   [`publish_issue!`](#publish_issue)&lt;br/&gt;    *   Publishes an `Issue` event (Kind 1621) to report bugs, request features, or track tasks.&lt;br/&gt;&lt;br/&gt;### Running NIP-34 Examples&lt;br/&gt;&lt;br/&gt;To see these macros in action, navigate to the `examples/` directory and run each example individually with the `nostr` feature enabled:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --example repository_announcement --features nostr&lt;br/&gt;cargo run --example publish_patch --features nostr&lt;br/&gt;cargo run --example publish_pull_request --features nostr&lt;br/&gt;cargo run --example publish_pr_update --features nostr&lt;br/&gt;cargo run --example publish_repository_state --features nostr&lt;br/&gt;cargo run --example publish_issue --features nostr&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`readme.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;readme.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    let build_message = if BUILD_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let cargo_message = if CARGO_TOML_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let lib_message = if LIB_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}{}&amp;#34;, README_TEMPLATE_PART0, README_TEMPLATE_PART1, README_TEMPLATE_PART_NIP34);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, BUILD_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, build_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART3);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, cargo_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART4);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, LIB_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, lib_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:40:01Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqswadlc7xxq8vp95vnhe3799g4dfkx8yg6dsgvm7x6n70l5hv04ywgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj28zd4v</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqswadlc7xxq8vp95vnhe3799g4dfkx8yg6dsgvm7x6n70l5hv04ywgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj28zd4v" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let file_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, file_hash);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;## Setup and Building&lt;br/&gt;&lt;br/&gt;1.  **Clone the repository:**&lt;br/&gt;    ```bash&lt;br/&gt;    git clone &amp;lt;repository-url&amp;gt;&lt;br/&gt;    cd &amp;lt;repository-name&amp;gt;&lt;br/&gt;    ```&lt;br/&gt;2.  **Build the project:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build&lt;br/&gt;    ```&lt;br/&gt;    During the build, `build.rs` will execute and print the hash of `Cargo.toml`.&lt;br/&gt;3.  **Run the example executable:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo run --bin get_file_hash&lt;br/&gt;    ```&lt;br/&gt;    This will print the hash of `src/bin/get_file_hash.rs` to your console.&lt;br/&gt;&lt;br/&gt;## Updating this `README.md`&lt;br/&gt;&lt;br/&gt;The hash information in this `README.md` is automatically generated by running the example executable.&lt;br/&gt;To update it, execute:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin get_file_hash &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## Current File Hash Information (of `src/bin/get_file_hash.rs`)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/get_file_hash.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`get_file_hash.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}&amp;#34;, README_TEMPLATE_PART1, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:39:49Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqszlstjwn29lf5dtxetalun0vpr26zphv308rplmwxufha38g8g0nszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjnju4c4</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] fn main() -&amp;gt; Result&amp;lt;(), ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqszlstjwn29lf5dtxetalun0vpr26zphv308rplmwxufha38g8g0nszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjnju4c4" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    get_file_hash_core::frost_mailbox_logic::simulate_frost_mailbox_post_signer()&lt;br/&gt;}&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_mailbox_post --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:39:49Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsdlnwegnp99ufw64eq8yz9ua4ra4qa779t0dqld63c3qwzpufyr5czyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj0hmfcj</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsdlnwegnp99ufw64eq8yz9ua4ra4qa779t0dqld63c3qwzpufyr5czyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj0hmfcj" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_repository_state;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let branch_name = &amp;#34;main&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Publishing repository state...&amp;#34;);&lt;br/&gt;    publish_repository_state!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        branch_name,&lt;br/&gt;        commit_id&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository state published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_repository_state --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:39:47Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsp8ddkqvu26u9nwj9axk7cq4ygvpwweve6eek7etcq8ldwpznjuvczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavja6w670</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsp8ddkqvu26u9nwj9axk7cq4ygvpwweve6eek7etcq8ldwpznjuvczyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavja6w670" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let max_signers = 3;&lt;br/&gt;    let min_signers = 2;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 0: Key Generation (Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    // In a real P2P setup, you&amp;#39;d use Distributed Key Generation (DKG).&lt;br/&gt;    // For local testing/simulations, the trusted dealer is faster.&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verifying the public key exists&lt;br/&gt;    let group_public_key = pubkey_package.verifying_key();&lt;br/&gt;    println!(&amp;#34;Group Public Key: {:?}&amp;#34;, group_public_key);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 1: Commitment&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let message = b&amp;#34;BIP-64MOD Consensus Proposal&amp;#34;;&lt;br/&gt;    let mut signing_commitments = BTreeMap::new();&lt;br/&gt;    let mut participant_nonces = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    // Participants 1 and 2 decide to sign&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        &lt;br/&gt;        // Generate nonces and commitments&lt;br/&gt;        let (nonces, commitments) = frost::round1::commit(&lt;br/&gt;            shares[&amp;amp;identifier].signing_share(),&lt;br/&gt;            &amp;amp;mut rng,&lt;br/&gt;        );&lt;br/&gt;        &lt;br/&gt;        signing_commitments.insert(identifier, commitments);&lt;br/&gt;        participant_nonces.insert(identifier, nonces);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 2: Signing&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let mut signature_shares = BTreeMap::new();&lt;br/&gt;    let signing_package = frost::SigningPackage::new(signing_commitments, message);&lt;br/&gt;&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        let nonces = &amp;amp;participant_nonces[&amp;amp;identifier];&lt;br/&gt;        &lt;br/&gt;        // Each participant produces a signature share&lt;br/&gt;        let key_package: frost::keys::KeyPackage = shares[&amp;amp;identifier].clone().try_into()?;&lt;br/&gt;        let share = frost::round2::sign(&amp;amp;signing_package, nonces, &amp;amp;key_package)?;&lt;br/&gt;        signature_shares.insert(identifier, share);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Finalization: Aggregation&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let group_signature = frost::aggregate(&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;signature_shares,&lt;br/&gt;        &amp;amp;pubkey_package,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verification&lt;br/&gt;    group_public_key.verify(message, &amp;amp;group_signature)?;&lt;br/&gt;    &lt;br/&gt;    println!(&amp;#34;Threshold signature verified successfully!&amp;#34;);&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example trusted-dealer --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:39:34Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsfq0u8gtnwsa3zgphc7h84c9aapvzgmpxaheepegqde52asj4nx4gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjghna46</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] fn main() -&amp;gt; Result&amp;lt;(), ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsfq0u8gtnwsa3zgphc7h84c9aapvzgmpxaheepegqde52asj4nx4gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjghna46" />
    <content type="html">
      &lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    get_file_hash_core::frost_mailbox_logic::simulate_frost_mailbox_coordinator()&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_mailbox --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:39:32Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs0ezqzvz3sp9a496mcyhm3n45dnk7n9svy94zjl70duhaktdrztdszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj5qjw9h</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs0ezqzvz3sp9a496mcyhm3n45dnk7n9svy94zjl70duhaktdrztdszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj5qjw9h" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_pull_request;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;0123456789abcdef0123456789abcdef01234567&amp;#34;;&lt;br/&gt;    let clone_url = &amp;#34;git@github.com:user/my-feature-branch.git&amp;#34;;&lt;br/&gt;    let title = Some(&amp;#34;Feat: Add new awesome feature example&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without title and build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request without title and build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request without title and build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With title but without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request with title but without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        title&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with title but without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 3: With build_manifest_event_id but without title&lt;br/&gt;    println!(&amp;#34;Publishing pull request with build_manifest_event_id but without title...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        None, // Explicitly pass None for title&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with build_manifest_event_id but without title published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 4: With title and build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request with title and build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        title,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with title and build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_pull_request --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:39:29Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs0jw0lu03z3vnrpshqvfha03eleq9zuzrhvgrph836lmme24jfzegzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjq4up6v</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs0jw0lu03z3vnrpshqvfha03eleq9zuzrhvgrph836lmme24jfzegzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjq4up6v" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;/// A simplified ROAST Coordinator that manages signing sessions&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;struct RoastCoordinator {&lt;br/&gt;    min_signers: u16,&lt;br/&gt;    _message: Vec&amp;lt;u8&amp;gt;,&lt;br/&gt;    commitments: BTreeMap&amp;lt;frost::Identifier, frost::round1::SigningCommitments&amp;gt;,&lt;br/&gt;    nonces: BTreeMap&amp;lt;frost::Identifier, frost::round1::SigningNonces&amp;gt;,&lt;br/&gt;    shares: BTreeMap&amp;lt;frost::Identifier, frost::round2::SignatureShare&amp;gt;,&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;impl RoastCoordinator {&lt;br/&gt;    fn new(min_signers: u16, message: &amp;amp;[u8]) -&amp;gt; Self {&lt;br/&gt;        Self {&lt;br/&gt;            min_signers,&lt;br/&gt;            _message: message.to_vec(),&lt;br/&gt;            commitments: BTreeMap::new(),&lt;br/&gt;            nonces: BTreeMap::new(),&lt;br/&gt;            shares: BTreeMap::new(),&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// ROAST Logic: Collect commitments until we hit the threshold.&lt;br/&gt;    /// In a real P2P system, this would be an async stream handler.&lt;br/&gt;    fn add_commitment(&amp;amp;mut self, id: frost::Identifier, comms: frost::round1::SigningCommitments, nonces: frost::round1::SigningNonces) {&lt;br/&gt;        if self.commitments.len() &amp;lt; self.min_signers as usize {&lt;br/&gt;            self.commitments.insert(id, comms);&lt;br/&gt;            self.nonces.insert(id, nonces);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// ROAST Logic: Collect signature shares.&lt;br/&gt;    fn add_share(&amp;amp;mut self, id: frost::Identifier, share: frost::round2::SignatureShare) {&lt;br/&gt;        if self.shares.len() &amp;lt; self.min_signers as usize {&lt;br/&gt;            self.shares.insert(id, share);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    fn is_ready_to_sign(&amp;amp;self) -&amp;gt; bool {&lt;br/&gt;        self.commitments.len() &amp;gt;= self.min_signers as usize&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    fn is_ready_to_aggregate(&amp;amp;self) -&amp;gt; bool {&lt;br/&gt;        self.shares.len() &amp;gt;= self.min_signers as usize&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (5, 3);&lt;br/&gt;    let message = b&amp;#34;BIP-64MOD Context: ROAST Coordination&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // 1. Setup: Generate keys (Dealer mode for simulation)&lt;br/&gt;    let (key_shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    let mut coordinator = RoastCoordinator::new(min_signers, message);&lt;br/&gt;&lt;br/&gt;    // 2. Round 1: Asynchronous Commitment Collection&lt;br/&gt;    // Simulate signers 1, 3, and 5 responding first (ROAST skips 2 and 4)&lt;br/&gt;    for &amp;amp;id_num in &amp;amp;[1, 3, 5] {&lt;br/&gt;        let id = frost::Identifier::try_from(id_num as u16)?;&lt;br/&gt;        let (nonces, comms) = frost::round1::commit(key_shares[&amp;amp;id].signing_share(), &amp;amp;mut rng);&lt;br/&gt;        &lt;br/&gt;        // Signers store their nonces locally, send comms to coordinator&lt;br/&gt;        coordinator.add_commitment(id, comms, nonces);&lt;br/&gt;        &lt;br/&gt;        // Note: Signer 2 was &amp;#34;offline&amp;#34;, but ROAST doesn&amp;#39;t care because we hit 3/5.&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 3. Round 2: Signing&lt;br/&gt;    if coordinator.is_ready_to_sign() {&lt;br/&gt;        let signing_package = frost::SigningPackage::new(coordinator.commitments.clone(), message);&lt;br/&gt;        &lt;br/&gt;        let mut temp_shares = BTreeMap::new();&lt;br/&gt;        for &amp;amp;id in coordinator.commitments.keys() {&lt;br/&gt;            // In reality, coordinator sends signing_package to signers&lt;br/&gt;            // Here we simulate the signers producing shares&lt;br/&gt;&lt;br/&gt;            let nonces = &amp;amp;coordinator.nonces[&amp;amp;id];&lt;br/&gt;            &lt;br/&gt;            let key_package: frost::keys::KeyPackage = key_shares[&amp;amp;id].clone().try_into()?;&lt;br/&gt;            let share = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces, &amp;amp;key_package)?;&lt;br/&gt;            temp_shares.insert(id, share);&lt;br/&gt;        }&lt;br/&gt;        for (id, share) in temp_shares {&lt;br/&gt;            coordinator.add_share(id, share);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 4. Finalization: Aggregation&lt;br/&gt;    if coordinator.is_ready_to_aggregate() {&lt;br/&gt;        let signing_package = frost::SigningPackage::new(coordinator.commitments.clone(), message);&lt;br/&gt;        let group_signature = frost::aggregate(&lt;br/&gt;            &amp;amp;signing_package,&lt;br/&gt;            &amp;amp;coordinator.shares,&lt;br/&gt;            &amp;amp;pubkey_package,&lt;br/&gt;        )?;&lt;br/&gt;&lt;br/&gt;        pubkey_package.verifying_key().verify(message, &amp;amp;group_signature)?;&lt;br/&gt;        println!(&amp;#34;ROAST-coordinated signature verified!&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example roast-experiment --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:39:23Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsz7m937xmfgvpuquxned7g8rd7wkjvp2gd5qhs267dltpvv0acchszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjqll2xy</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsz7m937xmfgvpuquxned7g8rd7wkjvp2gd5qhs267dltpvv0acchszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjqll2xy" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost; // MUST use the -tr variant for BIP-340/Nostr&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use serde_json::json;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use hex;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (3, 2);&lt;br/&gt;&lt;br/&gt;    // 1. Setup Nostr Event Metadata&lt;br/&gt;    let pubkey_hex = &amp;#34;79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798&amp;#34;; // Example&lt;br/&gt;    let created_at = 1712050000;&lt;br/&gt;    let kind = 1;&lt;br/&gt;    let content = &amp;#34;Hello from ROAST threshold signatures!&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    // 2. Serialize for Nostr ID (per NIP-01)&lt;br/&gt;    let event_json = json!([&lt;br/&gt;        0,&lt;br/&gt;        pubkey_hex,&lt;br/&gt;        created_at,&lt;br/&gt;        kind,&lt;br/&gt;        [],&lt;br/&gt;        content&lt;br/&gt;    ]).to_string();&lt;br/&gt;    &lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(event_json.as_bytes());&lt;br/&gt;    let event_id = hasher.finalize(); // This 32-byte hash is our signing message&lt;br/&gt;&lt;br/&gt;    // 3. FROST/ROAST Key Generation&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // 4. ROAST Coordination Simulation (Round 1: Commitments)&lt;br/&gt;    // In ROAST, the coordinator keeps a &amp;#34;session&amp;#34; open and collects commitments&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    let mut signer_nonces = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    // Signers 1 and 3 respond first (Signer 2 is offline/slow)&lt;br/&gt;    for &amp;amp;id_val in &amp;amp;[1, 3] {&lt;br/&gt;        let id = frost::Identifier::try_from(id_val as u16)?;&lt;br/&gt;        let (nonces, comms) = frost::round1::commit(shares[&amp;amp;id].signing_share(), &amp;amp;mut rng);&lt;br/&gt;        session_commitments.insert(id, comms);&lt;br/&gt;        signer_nonces.insert(id, nonces);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 5. Round 2: Signing the Nostr ID&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments, &amp;amp;event_id);&lt;br/&gt;    let mut signature_shares = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    for (id, nonces) in signer_nonces {&lt;br/&gt;        let key_package: frost::keys::KeyPackage = shares[&amp;amp;id].clone().try_into()?;&lt;br/&gt;        let share = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces, &amp;amp;key_package)?;&lt;br/&gt;        signature_shares.insert(id, share);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 6. Aggregate into a BIP-340 Signature&lt;br/&gt;    let group_signature = frost::aggregate(&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;signature_shares,&lt;br/&gt;        &amp;amp;pubkey_package,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // 7. Verification (using BIP-340 logic)&lt;br/&gt;    pubkey_package.verifying_key().verify(&amp;amp;event_id, &amp;amp;group_signature)?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Nostr Event ID: {}&amp;#34;, hex::encode(event_id));&lt;br/&gt;    println!(&amp;#34;Threshold Signature (BIP-340): {}&amp;#34;, hex::encode(group_signature.serialize()?));&lt;br/&gt;    println!(&amp;#34;Successfully signed Nostr event using ROAST/FROST!&amp;#34;);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_bip_340 --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:39:13Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs8zj2nf7cyxdrtxjw8acxjlrqen4phny0rxr0yz87kxz5mrydgzcgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjmy3252</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs8zj2nf7cyxdrtxjw8acxjlrqen4phny0rxr0yz87kxz5mrydgzcgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjmy3252" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[allow(unused_imports)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::repository_announcement;&lt;br/&gt;    use get_file_hash_core::get_file_hash;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use sha2::{Digest, Sha256};&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let project_name = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let description = &amp;#34;A fantastic new project example.&amp;#34;;&lt;br/&gt;    let clone_url = &amp;#34;git@github.com:user/my-awesome-repo-example.git&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing repository announcement without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    repository_announcement!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        project_name,&lt;br/&gt;        description,&lt;br/&gt;        clone_url,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use a known file in your project&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository announcement without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing repository announcement with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    repository_announcement!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        project_name,&lt;br/&gt;        description,&lt;br/&gt;        clone_url,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use a known file in your project&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository announcement with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example repository_announcement --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:39:11Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsxd3shu7dusyq70k0pmk2hzqyf2t2ewj493gw8ahv0hr6czny820czyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj88qtd3</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsxd3shu7dusyq70k0pmk2hzqyf2t2ewj493gw8ahv0hr6czny820czyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj88qtd3" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_pr_update;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let pr_event_id = EventId::from_str(&amp;#34;f6e4d6a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9&amp;#34;).unwrap(); // Example PR Event ID&lt;br/&gt;    let updated_commit_id = &amp;#34;z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0&amp;#34;;&lt;br/&gt;    let updated_clone_url = &amp;#34;git@github.com:user/my-feature-branch-v2.git&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_pr_update --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:39:10Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs8gvuw5eeew8ff2zjj79zdu4luhyqxdnynmftxv3e602zzvn0st2gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj9hung4</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs8gvuw5eeew8ff2zjj79zdu4luhyqxdnynmftxv3e602zzvn0st2gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj9hung4" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use get_file_hash_core::{get_relay_urls, publish_patch, publish_metadata_event, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-gnostr-repository-patch-with-metadata-example&amp;#34;; // Repository identifier&lt;br/&gt;    let commit_id = &amp;#34;f1e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6b7a8f9e0&amp;#34;; // Example commit ID&lt;br/&gt;&lt;br/&gt;    // Metadata for NIP-01 event&lt;br/&gt;    let picture_url = DEFAULT_PICTURE_URL;&lt;br/&gt;    let banner_url = DEFAULT_BANNER_URL;&lt;br/&gt;    let metadata_file_path = &amp;#34;./README.md&amp;#34;; // Using README.md content for metadata&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Publishing NIP-01 Metadata Event...&amp;#34;);&lt;br/&gt;    publish_metadata_event(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        picture_url,&lt;br/&gt;        banner_url,&lt;br/&gt;        metadata_file_path&lt;br/&gt;    ).await;&lt;br/&gt;    println!(&amp;#34;NIP-01 Metadata Event published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;&lt;br/&gt;Publishing NIP-34 Patch Event without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use an existing file for the patch content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;NIP-34 Patch Event without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;&lt;br/&gt;Publishing NIP-34 Patch Event with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;NIP-34 Patch Event with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_patch_with_metadata --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:38:59Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsdtpazyfswqnwrkn2qvhq9zhlpv95j3mjzrkhnuq0hu78skhky55qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjujd6c3</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsdtpazyfswqnwrkn2qvhq9zhlpv95j3mjzrkhnuq0hu78skhky55qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjujd6c3" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_repository_state;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let branch_name = &amp;#34;main&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Publishing repository state...&amp;#34;);&lt;br/&gt;    publish_repository_state!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        branch_name,&lt;br/&gt;        commit_id&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository state published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_repository_state --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:38:56Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs8e5ukq2cuq67w0w5y5f33k6070x0efxx3sgkg7f3kdj0jdz9fhfqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj2lsway</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use rand_chacha::ChaCha20Rng; ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs8e5ukq2cuq67w0w5y5f33k6070x0efxx3sgkg7f3kdj0jdz9fhfqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj2lsway" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand_chacha::ChaCha20Rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand_chacha::rand_core::SeedableRng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use hex;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost; &lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost::keys::IdentifierList;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    // 1. Create a deterministic seed (e.g., 32 bytes of zeros or a Git Hash)&lt;br/&gt;    let seed_hex = &amp;#34;473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813&amp;#34;;&lt;br/&gt;    let seed_bytes = hex::decode(seed_hex)?;&lt;br/&gt;    let mut rng = ChaCha20Rng::from_seed(seed_bytes.try_into().map_err(|_| &amp;#34;Invalid seed length&amp;#34;)?);&lt;br/&gt;&lt;br/&gt;    let max_signers = 3;&lt;br/&gt;    let min_signers = 2;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 0: Key Generation (Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;&lt;br/&gt;    // Using IdentifierList::Default creates identifiers 1, 2, 3...&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;--- Deterministic FROST Dealer ---&amp;#34;);&lt;br/&gt;    println!(&amp;#34;Threshold: {} of {}&amp;#34;, min_signers, max_signers);&lt;br/&gt;    println!(&amp;#34;Number of shares generated: {}&amp;#34;, shares.len()); &lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;\n--- Verifying Shares Against Commitments ---&amp;#34;);&lt;br/&gt;    for (identifier, share) in &amp;amp;shares {&lt;br/&gt;&lt;br/&gt;        // The Deterministic Values (Scalar Hex)&lt;br/&gt;        // Because your seed is fixed to the EMPTY_BLOB_SHA256,&lt;br/&gt;        // the &amp;#34;redacted&amp;#34; values in your output are always the same.&lt;br/&gt;        // Here are the Secret Signing Shares (the private scalars) for your 2-of-3 setup:&lt;br/&gt;        //&lt;br/&gt;        // Participant,Identifier (x),Signing Share (f(x)) in Hex&lt;br/&gt;        // Participant 1,...0001,757f49553754988450d995c65a0459a0f5a703d7c585f95f468202d09a365f57&lt;br/&gt;        // Participant 2,...0002,a3c4835e32308cb11b43968962290bc9171f1f1ca90c21741890e4f326f9879b&lt;br/&gt;        // Participant 3,...0003,d209bd672d0c80dd65ad974c6a4dc1f138973a618c924988eaaa0715b3bcafdf&lt;br/&gt;        //&lt;br/&gt;        // println!(&amp;#34;Participant Identifier: {:?} {:?}&amp;#34;, identifier, _share);&lt;br/&gt;        //&lt;br/&gt;&lt;br/&gt;        // In FROST, the &amp;#39;verify&amp;#39; method checks the share against the VSS commitment&lt;br/&gt;        match share.verify() {&lt;br/&gt;            Ok(_) =&amp;gt; {&lt;br/&gt;                println!(&amp;#34;Participant {:?}: Valid  ✅&amp;#34;, identifier);&lt;br/&gt;            }&lt;br/&gt;            Err(e) =&amp;gt; {&lt;br/&gt;                println!(&amp;#34;Participant {:?}: INVALID! ❌ Error: {:?}&amp;#34;, identifier, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    let pubkey_bytes = pubkey_package.verifying_key().serialize()?;&lt;br/&gt;    println!(&amp;#34;Group Public Key (Hex Compressed): {}&amp;#34;, hex::encode(&amp;amp;pubkey_bytes));&lt;br/&gt;    let x_only_hex = hex::encode(&amp;amp;pubkey_bytes[1..]);&lt;br/&gt;    println!(&amp;#34;Group Public Key (Hex X-Only):       {}&amp;#34;, x_only_hex);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;Run with --features nostr to enable this example.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:38:56Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs8836c5qv9ljtfhshgeses2gu4u96d3pfs0wrpp654nlny0sdwnqszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjclzu9u</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs8836c5qv9ljtfhshgeses2gu4u96d3pfs0wrpp654nlny0sdwnqszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjclzu9u" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use get_file_hash_core::{get_git_tracked_files, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event, publish_patch_event};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_patch;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;; // Example commit ID&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use an existing file for the patch content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_patch --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:38:47Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqspqlc78dkngy4ps77mh0u2j25ke2nrp63wu2mrs0d4z039h5jqtuszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjq0gwru</id>
    
      <title type="html"># dist plan --output-format=json &amp;gt; plan-dist-manifest.json # ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqspqlc78dkngy4ps77mh0u2j25ke2nrp63wu2mrs0d4z039h5jqtuszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjq0gwru" />
    <content type="html">
      # dist plan --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;# Config for &amp;#39;dist&amp;#39;&lt;br/&gt;[workspace]&lt;br/&gt;members = [&amp;#34;cargo:.&amp;#34;, &amp;#34;cargo:src/get_file_hash_core&amp;#34;]&lt;br/&gt;&lt;br/&gt;# Config for &amp;#39;dist&amp;#39;&lt;br/&gt;[dist]&lt;br/&gt;# The preferred dist version to use in CI (Cargo.toml SemVer syntax)&lt;br/&gt;cargo-dist-version = &amp;#34;0.30.3&amp;#34;&lt;br/&gt;# CI backends to support&lt;br/&gt;ci = &amp;#34;github&amp;#34;&lt;br/&gt;# The installers to generate for each app&lt;br/&gt;installers = [&amp;#34;shell&amp;#34;, &amp;#34;powershell&amp;#34;, &amp;#34;homebrew&amp;#34;, &amp;#34;msi&amp;#34;]&lt;br/&gt;# A GitHub repo to push Homebrew formulas to&lt;br/&gt;tap = &amp;#34;gnostr-org/homebrew-gnostr-org&amp;#34;&lt;br/&gt;# Path that installers should place binaries in&lt;br/&gt;install-path = &amp;#34;CARGO_HOME&amp;#34;&lt;br/&gt;# Publish jobs to run in CI&lt;br/&gt;publish-jobs = [&amp;#34;homebrew&amp;#34;]&lt;br/&gt;# Whether to install an updater program&lt;br/&gt;install-updater = true&lt;br/&gt;# Target platforms to build apps for (Rust target-triple syntax)&lt;br/&gt;targets = [&amp;#34;aarch64-apple-darwin&amp;#34;, &amp;#34;aarch64-unknown-linux-gnu&amp;#34;, &amp;#34;x86_64-apple-darwin&amp;#34;, &amp;#34;x86_64-unknown-linux-gnu&amp;#34;, &amp;#34;x86_64-unknown-linux-musl&amp;#34;, &amp;#34;x86_64-pc-windows-msvc&amp;#34;]&lt;br/&gt;# Skip checking whether the specified configuration files are up to date&lt;br/&gt;allow-dirty = [&amp;#34;ci&amp;#34;]&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:38:36Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsq7dla4rx20zprua5vpkmrj8kw33jzr7nh39rry9yqspwg456xv7gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjk3r0au</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsq7dla4rx20zprua5vpkmrj8kw33jzr7nh39rry9yqspwg456xv7gzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjk3r0au" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_pull_request;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;0123456789abcdef0123456789abcdef01234567&amp;#34;;&lt;br/&gt;    let clone_url = &amp;#34;git@github.com:user/my-feature-branch.git&amp;#34;;&lt;br/&gt;    let title = Some(&amp;#34;Feat: Add new awesome feature example&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without title and build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request without title and build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request without title and build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With title but without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request with title but without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        title&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with title but without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 3: With build_manifest_event_id but without title&lt;br/&gt;    println!(&amp;#34;Publishing pull request with build_manifest_event_id but without title...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        None, // Explicitly pass None for title&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with build_manifest_event_id but without title published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 4: With title and build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request with title and build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        title,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with title and build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_pull_request --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:38:36Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqstpc8vz5kuvth5mvupxh9x0aa6nq6wqyf33mzshqr0hj0s2rwdt0qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj70v944</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqstpc8vz5kuvth5mvupxh9x0aa6nq6wqyf33mzshqr0hj0s2rwdt0qzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj70v944" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use get_file_hash_core::{get_relay_urls, publish_issue, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event, publish_patch_event};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-gnostr-repository-issue-example&amp;#34;; // Repository identifier&lt;br/&gt;    let issue_id_1 = &amp;#34;issue-001&amp;#34;; // Unique identifier for the first issue&lt;br/&gt;    let issue_id_2 = &amp;#34;issue-002&amp;#34;; // Unique identifier for the second issue&lt;br/&gt;    let title_1 = &amp;#34;Bug: Application crashes on startup&amp;#34;;&lt;br/&gt;    let content_1 = &amp;#34;The application fails to launch on macOS Ventura. It throws a &amp;#39;Segmentation Fault&amp;#39; error immediately after execution. This was observed on version `v1.2.3`.&lt;br/&gt;&lt;br/&gt;Steps to reproduce:&lt;br/&gt;1. Download `app-v1.2.3-macos.tar.gz`&lt;br/&gt;2. Extract the archive&lt;br/&gt;3. Run `./app`&lt;br/&gt;&lt;br/&gt;Expected behavior: Application launches successfully.&lt;br/&gt;Actual behavior: Application crashes with &amp;#39;Segmentation Fault&amp;#39;.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    let title_2 = &amp;#34;Feature Request: Dark Mode&amp;#34;;&lt;br/&gt;    let content_2 = &amp;#34;Users have requested a dark mode option to improve readability and reduce eye strain during prolonged use. This should be toggleable in the settings menu.&lt;br/&gt;&lt;br/&gt;Considerations:&lt;br/&gt;- Adherence to system dark mode settings.&lt;br/&gt;- Consistent styling across all UI components.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Publish an issue without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing issue &amp;#39;{}&amp;#39; without build_manifest_event_id...&amp;#34;, title_1);&lt;br/&gt;    publish_issue!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        issue_id_1,&lt;br/&gt;        title_1,&lt;br/&gt;        content_1&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Issue &amp;#39;{}&amp;#39; published.&amp;#34;, title_1);&lt;br/&gt;&lt;br/&gt;    // Example 2: Publish an issue with build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing issue &amp;#39;{}&amp;#39; with build_manifest_event_id...&amp;#34;, title_2);&lt;br/&gt;    publish_issue!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        issue_id_2,&lt;br/&gt;        title_2,&lt;br/&gt;        content_2,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Issue &amp;#39;{}&amp;#39; published.&amp;#34;, title_2);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_issue --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:38:27Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsfwwn98p7pfudup9ms6mded4hm6mrhe8rhkly3mar2qtvkppfds0szyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjukkzrl</id>
    
      <title type="html">/// deterministic nostr event build example // deterministic ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsfwwn98p7pfudup9ms6mded4hm6mrhe8rhkly3mar2qtvkppfds0szyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjukkzrl" />
    <content type="html">
      /// deterministic nostr event build example&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use get_file_hash_core::{get_git_tracked_files, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use nostr_sdk::{EventBuilder, Keys, Tag, SecretKey};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use std::fs;&lt;br/&gt;&lt;br/&gt;use std::path::PathBuf;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use ::hex;&lt;br/&gt;&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    let manifest_dir = std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap();&lt;br/&gt;    let is_git_repo = std::path::Path::new(&amp;amp;manifest_dir).join(&amp;#34;.git&amp;#34;).exists();&lt;br/&gt;    #[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;	#[allow(unused_mut)]&lt;br/&gt;    let mut git_branch_str = String::new();&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_NAME={}&amp;#34;, env!(&amp;#34;CARGO_PKG_NAME&amp;#34;));&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_VERSION={}&amp;#34;, env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;));&lt;br/&gt;&lt;br/&gt;    if is_git_repo {&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;&lt;br/&gt;        let git_branch_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;--abbrev-ref&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for branch name&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_branch_str = if git_branch_output.status.success() &amp;amp;&amp;amp; !git_branch_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_branch_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git branch command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_branch_output.status, String::from_utf8_lossy(&amp;amp;git_branch_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH={}&amp;#34;, git_branch_str);&lt;br/&gt;    } else {&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH=&amp;#34;);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH=&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=.git/HEAD&amp;#34;);&lt;br/&gt;&lt;br/&gt;    //#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    //let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;    let cargo_toml_hash = get_file_hash!(&amp;#34;Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_TOML_HASH={}&amp;#34;, cargo_toml_hash);&lt;br/&gt;&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=LIB_HASH={}&amp;#34;, lib_hash);&lt;br/&gt;&lt;br/&gt;    let build_hash = get_file_hash!(&amp;#34;build.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=BUILD_HASH={}&amp;#34;, build_hash);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=build.rs&amp;#34;);&lt;br/&gt;    let online_relays_csv_path = PathBuf::from(&amp;amp;manifest_dir).join(&amp;#34;src/get_file_hash_core/src/online_relays_gps.csv&amp;#34;);&lt;br/&gt;    if online_relays_csv_path.exists() {&lt;br/&gt;        println!(&amp;#34;cargo:rerun-if-changed={}&amp;#34;, online_relays_csv_path.to_str().unwrap());&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    if cfg!(not(debug_assertions)) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Nostr feature enabled: Build may take longer due to network operations (publishing events to relays).&amp;#34;);&lt;br/&gt;&lt;br/&gt;        // This code only runs in release builds&lt;br/&gt;        let package_version = std::env::var(&amp;#34;CARGO_PKG_VERSION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;        let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;        if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        let files_to_publish: Vec&amp;lt;String&amp;gt; = get_git_tracked_files(&amp;amp;PathBuf::from(&amp;amp;manifest_dir));&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;        // Create padded_commit_hash&lt;br/&gt;        let padded_commit_hash = format!(&amp;#34;{:0&amp;gt;64}&amp;#34;, &amp;amp;git_commit_hash_str);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=PADDED_COMMIT_HASH={}&amp;#34;, padded_commit_hash);&lt;br/&gt;        // Initialize client and keys once&lt;br/&gt;        let initial_secret_key = SecretKey::parse(&amp;amp;padded_commit_hash).expect(&amp;#34;Failed to create Nostr SecretKey from PADDED_COMMIT_HASH&amp;#34;);&lt;br/&gt;        let initial_keys = Keys::new(initial_secret_key);&lt;br/&gt;        let mut client = nostr_sdk::Client::new(initial_keys.clone());&lt;br/&gt;        let mut relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;        // Add relays to the client&lt;br/&gt;        for relay_url in relay_urls.iter() {&lt;br/&gt;            if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to add relay {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        client.connect().await;&lt;br/&gt;        println!(&amp;#34;cargo:warning=Added and connected to {} relays.&amp;#34;, relay_urls.len());&lt;br/&gt;&lt;br/&gt;        let mut published_event_ids: Vec&amp;lt;Tag&amp;gt; = Vec::new();&lt;br/&gt;        let mut total_bytes_sent: usize = 0;&lt;br/&gt;    &lt;br/&gt;        for file_path_str in &amp;amp;files_to_publish {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Processing file: {}&amp;#34;, file_path_str);&lt;br/&gt;            match fs::read(file_path_str) {&lt;br/&gt;                Ok(bytes) =&amp;gt; {&lt;br/&gt;                    let mut hasher = Sha256::new();&lt;br/&gt;                    hasher.update(&amp;amp;bytes);&lt;br/&gt;                    let result = hasher.finalize();&lt;br/&gt;                    let file_hash_hex = hex::encode(result);&lt;br/&gt;&lt;br/&gt;                    match SecretKey::from_hex(&amp;amp;file_hash_hex.clone()) {&lt;br/&gt;                        Ok(secret_key) =&amp;gt; {&lt;br/&gt;                            let keys = Keys::new(secret_key);&lt;br/&gt;                            let content = String::from_utf8_lossy(&amp;amp;bytes).into_owned();&lt;br/&gt;                            let tags = vec![&lt;br/&gt;                                Tag::parse([&amp;#34;file&amp;#34;, file_path_str].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                                Tag::parse([&amp;#34;version&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                            ];&lt;br/&gt;                            let event_builder = EventBuilder::text_note(content).tags(tags);&lt;br/&gt;&lt;br/&gt;                            if let Some(event_id) = publish_nostr_event_if_release(&amp;amp;mut client, file_hash_hex, keys.clone(), event_builder, &amp;amp;mut relay_urls, file_path_str, &amp;amp;output_dir, &amp;amp;mut total_bytes_sent).await {&lt;br/&gt;                                published_event_ids.push(Tag::event(event_id));&lt;br/&gt;                            }&lt;br/&gt;&lt;br/&gt;                            // Publish metadata event&lt;br/&gt;                            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                                &amp;amp;keys,&lt;br/&gt;                                &amp;amp;relay_urls,&lt;br/&gt;                                DEFAULT_PICTURE_URL,&lt;br/&gt;                                DEFAULT_BANNER_URL,&lt;br/&gt;                                file_path_str,&lt;br/&gt;                            ).await;&lt;br/&gt;                        }&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to derive Nostr secret key for {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                }&lt;br/&gt;                Err(e) =&amp;gt; {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to read file {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        // Create and publish the build_manifest&lt;br/&gt;        if !published_event_ids.is_empty() {&lt;br/&gt;&lt;br/&gt;            //TODO this will be either the default or detected from env vars PRIVATE_KEY&lt;br/&gt;            let keys = Keys::new(SecretKey::from_hex(DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr keys from DEFAULT_GNOSTR_KEY&amp;#34;));&lt;br/&gt;            let cloned_keys = keys.clone();&lt;br/&gt;            let content = format!(&amp;#34;Build manifest for get_file_hash v{}&amp;#34;, package_version);&lt;br/&gt;            let mut tags = vec![&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;            ];&lt;br/&gt;            tags.extend(published_event_ids);&lt;br/&gt;&lt;br/&gt;            let event_builder = EventBuilder::text_note(content.clone()).tags(tags);&lt;br/&gt;&lt;br/&gt;            if let Some(event_id) = publish_nostr_event_if_release(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                hex::encode(Sha256::digest(content.as_bytes())),&lt;br/&gt;                keys,&lt;br/&gt;                event_builder,&lt;br/&gt;                &amp;amp;mut relay_urls,&lt;br/&gt;                &amp;#34;build_manifest.json&amp;#34;,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;mut total_bytes_sent,&lt;br/&gt;            ).await {&lt;br/&gt;&lt;br/&gt;                let build_manifest_event_id = Some(event_id);&lt;br/&gt;&lt;br/&gt;            // Publish metadata event for the build manifest&lt;br/&gt;            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                &amp;amp;cloned_keys, // Use reference to cloned keys here&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                DEFAULT_PICTURE_URL,&lt;br/&gt;                DEFAULT_BANNER_URL,&lt;br/&gt;                &amp;amp;format!(&amp;#34;build_manifest:{}&amp;#34;, package_version),&lt;br/&gt;            ).await;&lt;br/&gt;            let git_commit_hash = &amp;amp;git_commit_hash_str;&lt;br/&gt;            let git_branch = &amp;amp;git_branch_str;&lt;br/&gt;            let repo_url = std::env::var(&amp;#34;CARGO_PKG_REPOSITORY&amp;#34;).unwrap();&lt;br/&gt;            let repo_name = std::env::var(&amp;#34;CARGO_PKG_NAME&amp;#34;).unwrap();&lt;br/&gt;            let repo_description = std::env::var(&amp;#34;CARGO_PKG_DESCRIPTION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;            let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;            if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            let announcement_keys = Keys::new(SecretKey::from_hex(build_manifest_event_id.unwrap().to_hex().as_str()).expect(&amp;#34;Failed to create Nostr keys from build_manifest_event_id&amp;#34;));&lt;br/&gt;            let announcement_pubkey_hex = announcement_keys.public_key().to_string();&lt;br/&gt;&lt;br/&gt;            // Publish NIP-34 Repository Announcement&lt;br/&gt;            if let Some(_event_id) = get_repo_announcement_event(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                &amp;amp;announcement_keys,&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                &amp;amp;repo_url,&lt;br/&gt;                &amp;amp;repo_name,&lt;br/&gt;                &amp;amp;repo_description,&lt;br/&gt;                &amp;amp;git_commit_hash,&lt;br/&gt;                &amp;amp;git_branch,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;announcement_pubkey_hex&lt;br/&gt;            ).await {&lt;br/&gt;                // Successfully published announcement&lt;br/&gt;            }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        println!(&amp;#34;cargo:warning=Total bytes sent to Nostr relays: {} bytes ({} MB)&amp;#34;, total_bytes_sent, total_bytes_sent as f64 / 1024.0 / 1024.0);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:38:18Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsytz63kum6ct8ckhqr68jsrz5z352j4qxqqm53v90h60tkgxc749szyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjh5d7wg</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsytz63kum6ct8ckhqr68jsrz5z352j4qxqqm53v90h60tkgxc749szyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjh5d7wg" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_pr_update;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let pr_event_id = EventId::from_str(&amp;#34;f6e4d6a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9&amp;#34;).unwrap(); // Example PR Event ID&lt;br/&gt;    let updated_commit_id = &amp;#34;z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0&amp;#34;;&lt;br/&gt;    let updated_clone_url = &amp;#34;git@github.com:user/my-feature-branch-v2.git&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_pr_update --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:38:18Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqswz7w8rxxymwjz0wpttt05tuschjretthz90vr5urlpysy55v3hwszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjc6ayls</id>
    
      <title type="html">/// deterministic nostr event build example // deterministic ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqswz7w8rxxymwjz0wpttt05tuschjretthz90vr5urlpysy55v3hwszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjc6ayls" />
    <content type="html">
      /// deterministic nostr event build example&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use get_file_hash_core::{get_git_tracked_files, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use nostr_sdk::{EventBuilder, Keys, Tag, SecretKey};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use std::fs;&lt;br/&gt;&lt;br/&gt;use std::path::PathBuf;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use ::hex;&lt;br/&gt;&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    let manifest_dir = std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap();&lt;br/&gt;    let is_git_repo = std::path::Path::new(&amp;amp;manifest_dir).join(&amp;#34;.git&amp;#34;).exists();&lt;br/&gt;    #[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;	#[allow(unused_mut)]&lt;br/&gt;    let mut git_branch_str = String::new();&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_NAME={}&amp;#34;, env!(&amp;#34;CARGO_PKG_NAME&amp;#34;));&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_VERSION={}&amp;#34;, env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;));&lt;br/&gt;&lt;br/&gt;    if is_git_repo {&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;&lt;br/&gt;        let git_branch_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;--abbrev-ref&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for branch name&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_branch_str = if git_branch_output.status.success() &amp;amp;&amp;amp; !git_branch_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_branch_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git branch command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_branch_output.status, String::from_utf8_lossy(&amp;amp;git_branch_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH={}&amp;#34;, git_branch_str);&lt;br/&gt;    } else {&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH=&amp;#34;);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH=&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=.git/HEAD&amp;#34;);&lt;br/&gt;&lt;br/&gt;    //#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    //let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;    let cargo_toml_hash = get_file_hash!(&amp;#34;../Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_TOML_HASH={}&amp;#34;, cargo_toml_hash);&lt;br/&gt;&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;../src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=LIB_HASH={}&amp;#34;, lib_hash);&lt;br/&gt;&lt;br/&gt;    let build_hash = get_file_hash!(&amp;#34;../build.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=BUILD_HASH={}&amp;#34;, build_hash);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=build.rs&amp;#34;);&lt;br/&gt;    let online_relays_csv_path = PathBuf::from(&amp;amp;manifest_dir).join(&amp;#34;src/get_file_hash_core/src/online_relays_gps.csv&amp;#34;);&lt;br/&gt;    if online_relays_csv_path.exists() {&lt;br/&gt;        println!(&amp;#34;cargo:rerun-if-changed={}&amp;#34;, online_relays_csv_path.to_str().unwrap());&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    if cfg!(not(debug_assertions)) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Nostr feature enabled: Build may take longer due to network operations (publishing events to relays).&amp;#34;);&lt;br/&gt;&lt;br/&gt;        // This code only runs in release builds&lt;br/&gt;        let package_version = std::env::var(&amp;#34;CARGO_PKG_VERSION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;        let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;        if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        let files_to_publish: Vec&amp;lt;String&amp;gt; = get_git_tracked_files(&amp;amp;PathBuf::from(&amp;amp;manifest_dir));&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;        // Create padded_commit_hash&lt;br/&gt;        let padded_commit_hash = format!(&amp;#34;{:0&amp;gt;64}&amp;#34;, &amp;amp;git_commit_hash_str);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=PADDED_COMMIT_HASH={}&amp;#34;, padded_commit_hash);&lt;br/&gt;        // Initialize client and keys once&lt;br/&gt;        let initial_secret_key = SecretKey::parse(&amp;amp;padded_commit_hash).expect(&amp;#34;Failed to create Nostr SecretKey from PADDED_COMMIT_HASH&amp;#34;);&lt;br/&gt;        let initial_keys = Keys::new(initial_secret_key);&lt;br/&gt;        let mut client = nostr_sdk::Client::new(initial_keys.clone());&lt;br/&gt;        let mut relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;        // Add relays to the client&lt;br/&gt;        for relay_url in relay_urls.iter() {&lt;br/&gt;            if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to add relay {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        client.connect().await;&lt;br/&gt;        println!(&amp;#34;cargo:warning=Added and connected to {} relays.&amp;#34;, relay_urls.len());&lt;br/&gt;&lt;br/&gt;        let mut published_event_ids: Vec&amp;lt;Tag&amp;gt; = Vec::new();&lt;br/&gt;        let mut total_bytes_sent: usize = 0;&lt;br/&gt;    &lt;br/&gt;        for file_path_str in &amp;amp;files_to_publish {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Processing file: {}&amp;#34;, file_path_str);&lt;br/&gt;            match fs::read(file_path_str) {&lt;br/&gt;                Ok(bytes) =&amp;gt; {&lt;br/&gt;                    let mut hasher = Sha256::new();&lt;br/&gt;                    hasher.update(&amp;amp;bytes);&lt;br/&gt;                    let result = hasher.finalize();&lt;br/&gt;                    let file_hash_hex = hex::encode(result);&lt;br/&gt;&lt;br/&gt;                    match SecretKey::from_hex(&amp;amp;file_hash_hex.clone()) {&lt;br/&gt;                        Ok(secret_key) =&amp;gt; {&lt;br/&gt;                            let keys = Keys::new(secret_key);&lt;br/&gt;                            let content = String::from_utf8_lossy(&amp;amp;bytes).into_owned();&lt;br/&gt;                            let tags = vec![&lt;br/&gt;                                Tag::parse([&amp;#34;file&amp;#34;, file_path_str].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                                Tag::parse([&amp;#34;version&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                            ];&lt;br/&gt;                            let event_builder = EventBuilder::text_note(content).tags(tags);&lt;br/&gt;&lt;br/&gt;                            if let Some(event_id) = publish_nostr_event_if_release(&amp;amp;mut client, file_hash_hex, keys.clone(), event_builder, &amp;amp;mut relay_urls, file_path_str, &amp;amp;output_dir, &amp;amp;mut total_bytes_sent).await {&lt;br/&gt;                                published_event_ids.push(Tag::event(event_id));&lt;br/&gt;                            }&lt;br/&gt;&lt;br/&gt;                            // Publish metadata event&lt;br/&gt;                            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                                &amp;amp;keys,&lt;br/&gt;                                &amp;amp;relay_urls,&lt;br/&gt;                                DEFAULT_PICTURE_URL,&lt;br/&gt;                                DEFAULT_BANNER_URL,&lt;br/&gt;                                file_path_str,&lt;br/&gt;                            ).await;&lt;br/&gt;                        }&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to derive Nostr secret key for {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                }&lt;br/&gt;                Err(e) =&amp;gt; {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to read file {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        // Create and publish the build_manifest&lt;br/&gt;        if !published_event_ids.is_empty() {&lt;br/&gt;&lt;br/&gt;            //TODO this will be either the default or detected from env vars PRIVATE_KEY&lt;br/&gt;            let keys = Keys::new(SecretKey::from_hex(DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr keys from DEFAULT_GNOSTR_KEY&amp;#34;));&lt;br/&gt;            let cloned_keys = keys.clone();&lt;br/&gt;            let content = format!(&amp;#34;Build manifest for get_file_hash v{}&amp;#34;, package_version);&lt;br/&gt;            let mut tags = vec![&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;            ];&lt;br/&gt;            tags.extend(published_event_ids);&lt;br/&gt;&lt;br/&gt;            let event_builder = EventBuilder::text_note(content.clone()).tags(tags);&lt;br/&gt;&lt;br/&gt;            if let Some(event_id) = publish_nostr_event_if_release(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                hex::encode(Sha256::digest(content.as_bytes())),&lt;br/&gt;                keys,&lt;br/&gt;                event_builder,&lt;br/&gt;                &amp;amp;mut relay_urls,&lt;br/&gt;                &amp;#34;build_manifest.json&amp;#34;,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;mut total_bytes_sent,&lt;br/&gt;            ).await {&lt;br/&gt;&lt;br/&gt;                let build_manifest_event_id = Some(event_id);&lt;br/&gt;&lt;br/&gt;            // Publish metadata event for the build manifest&lt;br/&gt;            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                &amp;amp;cloned_keys, // Use reference to cloned keys here&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                DEFAULT_PICTURE_URL,&lt;br/&gt;                DEFAULT_BANNER_URL,&lt;br/&gt;                &amp;amp;format!(&amp;#34;build_manifest:{}&amp;#34;, package_version),&lt;br/&gt;            ).await;&lt;br/&gt;            let git_commit_hash = &amp;amp;git_commit_hash_str;&lt;br/&gt;            let git_branch = &amp;amp;git_branch_str;&lt;br/&gt;            let repo_url = std::env::var(&amp;#34;CARGO_PKG_REPOSITORY&amp;#34;).unwrap();&lt;br/&gt;            let repo_name = std::env::var(&amp;#34;CARGO_PKG_NAME&amp;#34;).unwrap();&lt;br/&gt;            let repo_description = std::env::var(&amp;#34;CARGO_PKG_DESCRIPTION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;            let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;            if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            let announcement_keys = Keys::new(SecretKey::from_hex(build_manifest_event_id.unwrap().to_hex().as_str()).expect(&amp;#34;Failed to create Nostr keys from build_manifest_event_id&amp;#34;));&lt;br/&gt;            let announcement_pubkey_hex = announcement_keys.public_key().to_string();&lt;br/&gt;&lt;br/&gt;            // Publish NIP-34 Repository Announcement&lt;br/&gt;            if let Some(_event_id) = get_repo_announcement_event(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                &amp;amp;announcement_keys,&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                &amp;amp;repo_url,&lt;br/&gt;                &amp;amp;repo_name,&lt;br/&gt;                &amp;amp;repo_description,&lt;br/&gt;                &amp;amp;git_commit_hash,&lt;br/&gt;                &amp;amp;git_branch,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;announcement_pubkey_hex&lt;br/&gt;            ).await {&lt;br/&gt;                // Successfully published announcement&lt;br/&gt;            }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        println!(&amp;#34;cargo:warning=Total bytes sent to Nostr relays: {} bytes ({} MB)&amp;#34;, total_bytes_sent, total_bytes_sent as f64 / 1024.0 / 1024.0);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:38:07Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqswjalx02yr47jnh0k789y3pu5ap7rncv8nxznqlgkquqc8t2lc6eqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjnedamr</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqswjalx02yr47jnh0k789y3pu5ap7rncv8nxznqlgkquqc8t2lc6eqzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjnedamr" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use get_file_hash_core::{get_relay_urls, publish_patch, publish_metadata_event, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-gnostr-repository-patch-with-metadata-example&amp;#34;; // Repository identifier&lt;br/&gt;    let commit_id = &amp;#34;f1e2d3c4b5a6f7e8d9c0b1a2f3e4d5c6b7a8f9e0&amp;#34;; // Example commit ID&lt;br/&gt;&lt;br/&gt;    // Metadata for NIP-01 event&lt;br/&gt;    let picture_url = DEFAULT_PICTURE_URL;&lt;br/&gt;    let banner_url = DEFAULT_BANNER_URL;&lt;br/&gt;    let metadata_file_path = &amp;#34;./README.md&amp;#34;; // Using README.md content for metadata&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Publishing NIP-01 Metadata Event...&amp;#34;);&lt;br/&gt;    publish_metadata_event(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        picture_url,&lt;br/&gt;        banner_url,&lt;br/&gt;        metadata_file_path&lt;br/&gt;    ).await;&lt;br/&gt;    println!(&amp;#34;NIP-01 Metadata Event published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;&lt;br/&gt;Publishing NIP-34 Patch Event without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use an existing file for the patch content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;NIP-34 Patch Event without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;&lt;br/&gt;Publishing NIP-34 Patch Event with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;NIP-34 Patch Event with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_patch_with_metadata --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:37:59Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqspzzpz7afsw095qy43vlcl4dj490ypmuv6ek0rpeyhhhvh4e25nvszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjat4yhf</id>
    
      <title type="html"># `get_file_hash` macro This project provides a Rust procedural ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqspzzpz7afsw095qy43vlcl4dj490ypmuv6ek0rpeyhhhvh4e25nvszyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjat4yhf" />
    <content type="html">
      # `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use get_file_hash::CARGO_TOML_HASH;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let readme_hash = get_file_hash!(&amp;#34;src/bin/readme.rs&amp;#34;);&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, lib_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/bin/readme.rs is: {}&amp;#34;, readme_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of Cargo.toml is: {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## Release&lt;br/&gt;## [`README.md`](./README.md)&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin readme &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## [`src/bin/readme.rs`](src/bin/readme.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/readme.rs`&lt;br/&gt;## NIP-34 Integration: Git Repository Events on Nostr&lt;br/&gt;&lt;br/&gt;This library provides a set of powerful macros and functions for integrating Git repository events with the Nostr protocol, adhering to the [NIP-34: Git Repositories on Nostr](&lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/34.md&#34;&gt;https://github.com/nostr-protocol/nips/blob/master/34.md&lt;/a&gt;) specification.&lt;br/&gt;&lt;br/&gt;These tools allow you to publish various Git-related events to Nostr relays, enabling decentralized tracking and collaboration for your code repositories.&lt;br/&gt;&lt;br/&gt;### Available NIP-34 Macros&lt;br/&gt;&lt;br/&gt;Each macro provides a convenient way to publish specific NIP-34 event kinds:&lt;br/&gt;&lt;br/&gt;*   [`repository_announcement!`](#repository_announcement)&lt;br/&gt;    *   Publishes a `Repository Announcement` event (Kind 30617) to announce a new or updated Git repository.&lt;br/&gt;*   [`publish_patch!`](#publish_patch)&lt;br/&gt;    *   Publishes a `Patch` event (Kind 1617) containing a Git patch (diff) for a specific commit.&lt;br/&gt;*   [`publish_pull_request!`](#publish_pull_request)&lt;br/&gt;    *   Publishes a `Pull Request` event (Kind 1618) to propose changes and facilitate code review.&lt;br/&gt;*   [`publish_pr_update!`](#publish_pr_update)&lt;br/&gt;    *   Publishes a `Pull Request Update` event (Kind 1619) to update an existing pull request.&lt;br/&gt;*   [`publish_repository_state!`](#publish_repository_state)&lt;br/&gt;    *   Publishes a `Repository State` event (Kind 1620) to announce the current state of a branch (e.g., its latest commit).&lt;br/&gt;*   [`publish_issue!`](#publish_issue)&lt;br/&gt;    *   Publishes an `Issue` event (Kind 1621) to report bugs, request features, or track tasks.&lt;br/&gt;&lt;br/&gt;### Running NIP-34 Examples&lt;br/&gt;&lt;br/&gt;To see these macros in action, navigate to the `examples/` directory and run each example individually with the `nostr` feature enabled:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --example repository_announcement --features nostr&lt;br/&gt;cargo run --example publish_patch --features nostr&lt;br/&gt;cargo run --example publish_pull_request --features nostr&lt;br/&gt;cargo run --example publish_pr_update --features nostr&lt;br/&gt;cargo run --example publish_repository_state --features nostr&lt;br/&gt;cargo run --example publish_issue --features nostr&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;*   **SHA-256 Hash:** 6c6325c5a4c14f44cbda6ca53179ab3d6666ce7c916365668c6dd1d79215db59&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`build.rs`](build.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `build.rs`&lt;br/&gt;*   **SHA-256 Hash:** 20c958c8cbb5c77cf5eb3763b6da149b61241d328df52d39b7aa97903305c889&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`Cargo.toml`](Cargo.toml)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `Cargo.toml`&lt;br/&gt;*   **SHA-256 Hash:** e3f392bf23b5fb40902acd313a8c76d1943060b6805ea8615de62f9baf0c6513&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`src/lib.rs`](src/lib.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/lib.rs`&lt;br/&gt;*   **SHA-256 Hash:** 591593482a6c9aac8793aa1e488e613f52a4effb1ec3465fd9d6a54537f2b123&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:37:59Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsrwhmrn4jhfvh9vwmu3dexsdfg4k88xak5tt0pqk9pedkf6x2mllgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj6yw7p8</id>
    
      <title type="html">/// BIP-64MOD &#43; GCC: Complete Git Empty &amp;amp; Genesis Constants ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsrwhmrn4jhfvh9vwmu3dexsdfg4k88xak5tt0pqk9pedkf6x2mllgzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavj6yw7p8" />
    <content type="html">
      /// BIP-64MOD &#43; GCC: Complete Git Empty &amp;amp; Genesis Constants&lt;br/&gt;/// &lt;br/&gt;/// This module provides the standard cryptographic identifiers for &amp;#34;null&amp;#34;, &lt;br/&gt;/// &amp;#34;empty&amp;#34;, and &amp;#34;genesis&amp;#34; states, including NIP-19 (Bech32) identities.&lt;br/&gt;pub struct GitEmptyState;&lt;br/&gt;&lt;br/&gt;impl GitEmptyState {&lt;br/&gt;    // === NULL REFERENCE (Zero Hash) ===&lt;br/&gt;    pub const NULL_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;0000000000000000000000000000000000000000000000000000000000000000&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // === EMPTY BLOB (Empty File) ===&lt;br/&gt;    pub const BLOB_SHA1: &amp;amp;&amp;#39;static str = &amp;#34;e69de29bb2d1d6434b8b29ae775ad8c2e48c5391&amp;#34;;&lt;br/&gt;    pub const BLOB_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813&amp;#34;;&lt;br/&gt;    pub const BLOB_NSEC: &amp;amp;&amp;#39;static str = &amp;#34;nsec1guaq7npmaz5ndqdzvl3mr6d8mndprp2rdls5ram5jys2xqmjrqfsdzhrp6&amp;#34;;&lt;br/&gt;    pub const BLOB_NPUB: &amp;amp;&amp;#39;static str = &amp;#34;npub180cvv07tjdrghvkyh6964p7w9vsqpf3p05868v399v86p8y6f69sq5fdp0&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // === EMPTY TREE (Empty Directory) ===&lt;br/&gt;    pub const TREE_SHA1: &amp;amp;&amp;#39;static str = &amp;#34;4b825dc642cb6eb9a060e54bf8d69288fbee4904&amp;#34;;&lt;br/&gt;    pub const TREE_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321&amp;#34;;&lt;br/&gt;    pub const TREE_NSEC: &amp;amp;&amp;#39;static str = &amp;#34;nsec1dmceksfzt3fknuwpqn29mrv9a75mq4a48v2tfwde88whfhkv2vsslsc46c&amp;#34;;&lt;br/&gt;    pub const TREE_NPUB: &amp;amp;&amp;#39;static str = &amp;#34;npub1pxmpep6yk7z6p332u9588k0vscg26rv29pynvscg26rv29pynvsq6erdfh&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // === GENESIS COMMIT (DeepSpaceM1 @ Epoch 0) ===&lt;br/&gt;    /// Result of: git commit --allow-empty -m &amp;#39;Initial commit&amp;#39; &lt;br/&gt;    /// With Author/Committer: DeepSpaceM1 &amp;lt;ds_m1@gnostr.org&amp;gt; @ 1970-01-01T00:00:00Z&lt;br/&gt;    pub const GENESIS_AUTHOR_NAME: &amp;amp;&amp;#39;static str = &amp;#34;DeepSpaceM1&amp;#34;;&lt;br/&gt;    pub const GENESIS_AUTHOR_EMAIL: &amp;amp;&amp;#39;static str = &amp;#34;ds_m1@gnostr.org&amp;#34;;&lt;br/&gt;    pub const GENESIS_DATE_UNIX: i64 = 0;&lt;br/&gt;    pub const GENESIS_MESSAGE: &amp;amp;&amp;#39;static str = &amp;#34;Initial commit&amp;#34;;&lt;br/&gt;&lt;br/&gt;    /// The resulting SHA-256 Commit Hash for this specific configuration&lt;br/&gt;    pub const GENESIS_COMMIT_SHA256: &amp;amp;&amp;#39;static str = &amp;#34;e9768652d87e07663479a0ad402513f56d953930b659c2ef389d4d03d3623910&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    /// The NIP-19 Identity associated with the Genesis Commit&lt;br/&gt;    pub const GENESIS_NSEC: &amp;amp;&amp;#39;static str = &amp;#34;nsec1jpxmpep6yk7z6p332u9588k0vscg26rv29pynvscg26rv29pynvsq68at9d&amp;#34;;&lt;br/&gt;    pub const GENESIS_NPUB: &amp;amp;&amp;#39;static str = &amp;#34;npub1pxmpep6yk7z6p332u9588k0vscg26rv29pynvscg26rv29pynvsq6erdfh&amp;#34;;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Helper for constructing the commit object string for hashing&lt;br/&gt;pub mod builders {&lt;br/&gt;    use super::GitEmptyState;&lt;br/&gt;&lt;br/&gt;    pub fn build_genesis_commit_object() -&amp;gt; String {&lt;br/&gt;        format!(&lt;br/&gt;            &amp;#34;tree {}\nauthor {} &amp;lt;{}&amp;gt; {} &#43;0000\ncommitter {} &amp;lt;{}&amp;gt; {} &#43;0000\n\n{}\n&amp;#34;,&lt;br/&gt;            GitEmptyState::TREE_SHA256,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_NAME,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_EMAIL,&lt;br/&gt;            GitEmptyState::GENESIS_DATE_UNIX,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_NAME,&lt;br/&gt;            GitEmptyState::GENESIS_AUTHOR_EMAIL,&lt;br/&gt;            GitEmptyState::GENESIS_DATE_UNIX,&lt;br/&gt;            GitEmptyState::GENESIS_MESSAGE&lt;br/&gt;        )&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;--- BIP-64MOD &#43; GCC Genesis State ---&amp;#34;);&lt;br/&gt;    println!(&amp;#34;Commit Hash: {}&amp;#34;, GitEmptyState::GENESIS_COMMIT_SHA256);&lt;br/&gt;    println!(&amp;#34;Author:      {} &amp;lt;{}&amp;gt;&amp;#34;, GitEmptyState::GENESIS_AUTHOR_NAME, GitEmptyState::GENESIS_AUTHOR_EMAIL);&lt;br/&gt;    println!(&amp;#34;Timestamp:   {}&amp;#34;, GitEmptyState::GENESIS_DATE_UNIX);&lt;br/&gt;    println!(&amp;#34;NSEC:        {}&amp;#34;, GitEmptyState::GENESIS_NSEC);&lt;br/&gt;    &lt;br/&gt;    let object_raw = builders::build_genesis_commit_object();&lt;br/&gt;    println!(&amp;#34;\nRaw Git Commit Object:\n---\n{}---&amp;#34;, object_raw);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:37:54Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsxkxq3yf9xj55cf3ylype02l74lks8l56ywg62hal4gk5tmf8lsagzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjzg8wv5</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsxkxq3yf9xj55cf3ylype02l74lks8l56ywg62hal4gk5tmf8lsagzyqmnqcjsuc42l0sh7873acj62w0jdrsyf463vu6vdcufcm08yuavjzg8wv5" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use get_file_hash_core::{get_git_tracked_files, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL, publish_nostr_event_if_release, get_repo_announcement_event, publish_patch_event};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_patch;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;; // Example commit ID&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use an existing file for the patch content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_patch --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-04T01:37:47Z</updated>
  </entry>

</feed>