From b4f0c60ea0ff292d95016a8609c195003b508549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Mon, 15 Jan 2024 12:37:41 +0300 Subject: [PATCH] Update nostr gem, switch to Ruby for bech32 encoding --- Gemfile | 2 +- Gemfile.lock | 18 ++++++++++++------ .../settings/nostr_pubkey_controller.js | 10 ---------- app/models/user.rb | 7 +++++++ app/views/settings/_experiments.html.erb | 2 +- config/importmap.rb | 1 - spec/features/settings/experiments_spec.rb | 2 +- spec/models/user_spec.rb | 10 ++++++++++ vendor/javascript/bech32.js | 2 -- 9 files changed, 32 insertions(+), 22 deletions(-) delete mode 100644 vendor/javascript/bech32.js diff --git a/Gemfile b/Gemfile index df0e515..0318bf2 100644 --- a/Gemfile +++ b/Gemfile @@ -62,7 +62,7 @@ gem "sentry-rails" gem 'discourse_api' gem "lnurl" gem 'manifique', git: 'https://gitea.kosmos.org/5apps/manifique.git', branch: 'master' -gem 'nostr', git: 'https://gitea.kosmos.org/kosmos/nostr-gem.git', branch: 'feature/ruby_2.7_compat' +gem 'nostr', git: 'https://gitea.kosmos.org/kosmos/nostr-gem.git', ref: 'd59f31a' group :development, :test do # Use sqlite3 as the database for Active Record diff --git a/Gemfile.lock b/Gemfile.lock index 3e551f1..16a967c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,12 +10,12 @@ GIT GIT remote: https://gitea.kosmos.org/kosmos/nostr-gem.git - revision: 596529d9eb50d13b3f385245636698fccf37b442 - branch: feature/ruby_2.7_compat + revision: d59f31a3c63c7642fe2d3eb50b785da54fdabfab + ref: d59f31a specs: - nostr (0.4.0) - bech32 (~> 1.3) - bip-schnorr (~> 0.4) + nostr (0.5.0) + bech32 (~> 1.4) + bip-schnorr (~> 0.6) ecdsa (~> 1.2) event_emitter (~> 0.2) faye-websocket (~> 0.11) @@ -115,7 +115,7 @@ GEM thor (>= 1.1.0) benchmark (0.2.1) bindex (0.8.1) - bip-schnorr (0.6.0) + bip-schnorr (0.7.0) ecdsa_ext (~> 0.5.0) brow (0.4.1) builder (3.2.4) @@ -259,6 +259,7 @@ GEM method_source (1.0.0) mini_magick (4.12.0) mini_mime (1.1.5) + mini_portile2 (2.8.5) minitest (5.20.0) multipart-post (2.3.0) net-imap (0.3.7) @@ -272,6 +273,9 @@ GEM net-smtp (0.4.0) net-protocol nio4r (2.5.9) + nokogiri (1.15.4) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) nokogiri (1.15.4-arm64-darwin) racc (~> 1.4) nokogiri (1.15.4-x86_64-linux) @@ -422,6 +426,8 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) + sqlite3 (1.6.7) + mini_portile2 (~> 2.8.0) sqlite3 (1.6.7-arm64-darwin) sqlite3 (1.6.7-x86_64-linux) stimulus-rails (1.3.0) diff --git a/app/javascript/controllers/settings/nostr_pubkey_controller.js b/app/javascript/controllers/settings/nostr_pubkey_controller.js index 8d4d921..c65a8fa 100644 --- a/app/javascript/controllers/settings/nostr_pubkey_controller.js +++ b/app/javascript/controllers/settings/nostr_pubkey_controller.js @@ -1,5 +1,4 @@ import { Controller } from "@hotwired/stimulus" -import { bech32 } from "bech32" function hexToBytes (hex) { let bytes = [] @@ -15,10 +14,6 @@ export default class extends Controller { static values = { userAddress: String, pubkeyHex: String, sharedSecret: String } connect () { - if (this.hasPubkeyHexValue && this.pubkeyHexValue.length > 0) { - this.pubkeyBech32InputTarget.value = this.pubkeyBech32 - } - if (window.nostr) { if (this.hasSetPubkeyTarget) { this.setPubkeyTarget.disabled = false @@ -53,11 +48,6 @@ export default class extends Controller { } } - get pubkeyBech32 () { - const words = bech32.toWords(hexToBytes(this.pubkeyHexValue)) - return bech32.encode('npub', words) - } - get csrfToken () { const element = document.head.querySelector('meta[name="csrf-token"]') return element.getAttribute("content") diff --git a/app/models/user.rb b/app/models/user.rb index 9c933a3..34ab5ad 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,3 +1,5 @@ +require 'nostr' + class User < ApplicationRecord include EmailValidatable @@ -185,6 +187,11 @@ class User < ApplicationRecord ldap.delete_attribute(dn,:service) end + def nostr_pubkey_bech32 + return nil unless nostr_pubkey.present? + Nostr::PublicKey.new(nostr_pubkey).to_bech32 + end + private def ldap diff --git a/app/views/settings/_experiments.html.erb b/app/views/settings/_experiments.html.erb index ef5bd4a..3c1a5b2 100644 --- a/app/views/settings/_experiments.html.erb +++ b/app/views/settings/_experiments.html.erb @@ -7,7 +7,7 @@ data-settings--nostr-pubkey-pubkey-hex-value="<%= current_user.nostr_pubkey %>">

- <%= link_to nostr_pubkey_settings_path, diff --git a/config/importmap.rb b/config/importmap.rb index 2c52451..cb396cc 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -5,5 +5,4 @@ pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true pin_all_from "app/javascript/controllers", under: "controllers" -pin "bech32" # @2.0.0 pin "tailwindcss-stimulus-components" # @4.0.3 diff --git a/spec/features/settings/experiments_spec.rb b/spec/features/settings/experiments_spec.rb index d23ab25..dd43303 100644 --- a/spec/features/settings/experiments_spec.rb +++ b/spec/features/settings/experiments_spec.rb @@ -28,7 +28,7 @@ RSpec.describe 'Experimental Settings', type: :feature do scenario 'Remove nostr pubkey from account' do visit setting_path(:experiments) expect(page).to have_field("nostr_public_key", - with: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3", + with: "npub1qlsc3g0lsl8pw8230w8d9wm6xxcax3f6pkemz5measrmwfxjxteslf2hac", disabled: true) click_link "Remove" diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index a3e8051..83f35b7 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -205,4 +205,14 @@ RSpec.describe User, type: :model do end end end + + describe "#nostr_pubkey_bech32" do + before do + user.update! nostr_pubkey: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3" + end + + it "encodes the hexadecimal pubkey to bech32" do + expect(user.nostr_pubkey_bech32).to eq("npub1qlsc3g0lsl8pw8230w8d9wm6xxcax3f6pkemz5measrmwfxjxteslf2hac") + end + end end diff --git a/vendor/javascript/bech32.js b/vendor/javascript/bech32.js deleted file mode 100644 index 2e6c3ea..0000000 --- a/vendor/javascript/bech32.js +++ /dev/null @@ -1,2 +0,0 @@ -var e={};Object.defineProperty(e,"__esModule",{value:true});e.bech32m=e.bech32=void 0;const r="qpzry9x8gf2tvdw0s3jn54khce6mua7l";const t={};for(let e=0;e>25;return(33554431&e)<<5^996825010&-(r>>0&1)^642813549&-(r>>1&1)^513874426&-(r>>2&1)^1027748829&-(r>>3&1)^705979059&-(r>>4&1)}function prefixChk(e){let r=1;for(let t=0;t126)return"Invalid prefix ("+e+")";r=polymodStep(r)^o>>5}r=polymodStep(r);for(let t=0;t=t){c-=t;f.push(n>>c&s)}}if(o)c>0&&f.push(n<=r)return"Excess padding";if(n<n)throw new TypeError("Exceeds length limit");e=e.toLowerCase();let c=prefixChk(e);if("string"===typeof c)throw new Error(c);let s=e+"1";for(let e=0;e>5!==0)throw new Error("Non 5-bit word");c=polymodStep(c)^o;s+=r.charAt(o)}for(let e=0;e<6;++e)c=polymodStep(c);c^=o;for(let e=0;e<6;++e){const t=c>>5*(5-e)&31;s+=r.charAt(t)}return s}function __decode(e,r){r=r||90;if(e.length<8)return e+" too short";if(e.length>r)return"Exceeds length limit";const n=e.toLowerCase();const c=e.toUpperCase();if(e!==n&&e!==c)return"Mixed-case string "+e;e=n;const s=e.lastIndexOf("1");if(-1===s)return"No separator character for "+e;if(0===s)return"Missing prefix for "+e;const f=e.slice(0,s);const i=e.slice(s+1);if(i.length<6)return"Data too short";let d=prefixChk(f);if("string"===typeof d)return d;const l=[];for(let e=0;e=i.length||l.push(o)}return d!==o?"Invalid checksum for "+e:{prefix:f,words:l}}function decodeUnsafe(e,r){const t=__decode(e,r);if("object"===typeof t)return t}function decode(e,r){const t=__decode(e,r);if("object"===typeof t)return t;throw new Error(t)}return{decodeUnsafe:decodeUnsafe,decode:decode,encode:encode,toWords:toWords,fromWordsUnsafe:fromWordsUnsafe,fromWords:fromWords}}e.bech32=getLibraryFromEncoding("bech32");e.bech32m=getLibraryFromEncoding("bech32m");const o=e.__esModule,n=e.bech32m,c=e.bech32;export default e;export{o as __esModule,c as bech32,n as bech32m}; -