Update nostr gem, switch to Ruby for bech32 encoding
This commit is contained in:
		
							parent
							
								
									1a5a2177b4
								
							
						
					
					
						commit
						b4f0c60ea0
					
				
							
								
								
									
										2
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Gemfile
									
									
									
									
									
								
							| @ -62,7 +62,7 @@ gem "sentry-rails" | |||||||
| gem 'discourse_api' | gem 'discourse_api' | ||||||
| gem "lnurl" | gem "lnurl" | ||||||
| gem 'manifique', git: 'https://gitea.kosmos.org/5apps/manifique.git', branch: 'master' | 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 | group :development, :test do | ||||||
|   # Use sqlite3 as the database for Active Record |   # Use sqlite3 as the database for Active Record | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								Gemfile.lock
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								Gemfile.lock
									
									
									
									
									
								
							| @ -10,12 +10,12 @@ GIT | |||||||
| 
 | 
 | ||||||
| GIT | GIT | ||||||
|   remote: https://gitea.kosmos.org/kosmos/nostr-gem.git |   remote: https://gitea.kosmos.org/kosmos/nostr-gem.git | ||||||
|   revision: 596529d9eb50d13b3f385245636698fccf37b442 |   revision: d59f31a3c63c7642fe2d3eb50b785da54fdabfab | ||||||
|   branch: feature/ruby_2.7_compat |   ref: d59f31a | ||||||
|   specs: |   specs: | ||||||
|     nostr (0.4.0) |     nostr (0.5.0) | ||||||
|       bech32 (~> 1.3) |       bech32 (~> 1.4) | ||||||
|       bip-schnorr (~> 0.4) |       bip-schnorr (~> 0.6) | ||||||
|       ecdsa (~> 1.2) |       ecdsa (~> 1.2) | ||||||
|       event_emitter (~> 0.2) |       event_emitter (~> 0.2) | ||||||
|       faye-websocket (~> 0.11) |       faye-websocket (~> 0.11) | ||||||
| @ -115,7 +115,7 @@ GEM | |||||||
|       thor (>= 1.1.0) |       thor (>= 1.1.0) | ||||||
|     benchmark (0.2.1) |     benchmark (0.2.1) | ||||||
|     bindex (0.8.1) |     bindex (0.8.1) | ||||||
|     bip-schnorr (0.6.0) |     bip-schnorr (0.7.0) | ||||||
|       ecdsa_ext (~> 0.5.0) |       ecdsa_ext (~> 0.5.0) | ||||||
|     brow (0.4.1) |     brow (0.4.1) | ||||||
|     builder (3.2.4) |     builder (3.2.4) | ||||||
| @ -259,6 +259,7 @@ GEM | |||||||
|     method_source (1.0.0) |     method_source (1.0.0) | ||||||
|     mini_magick (4.12.0) |     mini_magick (4.12.0) | ||||||
|     mini_mime (1.1.5) |     mini_mime (1.1.5) | ||||||
|  |     mini_portile2 (2.8.5) | ||||||
|     minitest (5.20.0) |     minitest (5.20.0) | ||||||
|     multipart-post (2.3.0) |     multipart-post (2.3.0) | ||||||
|     net-imap (0.3.7) |     net-imap (0.3.7) | ||||||
| @ -272,6 +273,9 @@ GEM | |||||||
|     net-smtp (0.4.0) |     net-smtp (0.4.0) | ||||||
|       net-protocol |       net-protocol | ||||||
|     nio4r (2.5.9) |     nio4r (2.5.9) | ||||||
|  |     nokogiri (1.15.4) | ||||||
|  |       mini_portile2 (~> 2.8.2) | ||||||
|  |       racc (~> 1.4) | ||||||
|     nokogiri (1.15.4-arm64-darwin) |     nokogiri (1.15.4-arm64-darwin) | ||||||
|       racc (~> 1.4) |       racc (~> 1.4) | ||||||
|     nokogiri (1.15.4-x86_64-linux) |     nokogiri (1.15.4-x86_64-linux) | ||||||
| @ -422,6 +426,8 @@ GEM | |||||||
|       actionpack (>= 5.2) |       actionpack (>= 5.2) | ||||||
|       activesupport (>= 5.2) |       activesupport (>= 5.2) | ||||||
|       sprockets (>= 3.0.0) |       sprockets (>= 3.0.0) | ||||||
|  |     sqlite3 (1.6.7) | ||||||
|  |       mini_portile2 (~> 2.8.0) | ||||||
|     sqlite3 (1.6.7-arm64-darwin) |     sqlite3 (1.6.7-arm64-darwin) | ||||||
|     sqlite3 (1.6.7-x86_64-linux) |     sqlite3 (1.6.7-x86_64-linux) | ||||||
|     stimulus-rails (1.3.0) |     stimulus-rails (1.3.0) | ||||||
|  | |||||||
| @ -1,5 +1,4 @@ | |||||||
| import { Controller } from "@hotwired/stimulus" | import { Controller } from "@hotwired/stimulus" | ||||||
| import { bech32 } from "bech32" |  | ||||||
| 
 | 
 | ||||||
| function hexToBytes (hex) { | function hexToBytes (hex) { | ||||||
|   let bytes = [] |   let bytes = [] | ||||||
| @ -15,10 +14,6 @@ export default class extends Controller { | |||||||
|   static values  = { userAddress: String, pubkeyHex: String, sharedSecret: String } |   static values  = { userAddress: String, pubkeyHex: String, sharedSecret: String } | ||||||
| 
 | 
 | ||||||
|   connect () { |   connect () { | ||||||
|     if (this.hasPubkeyHexValue && this.pubkeyHexValue.length > 0) { |  | ||||||
|       this.pubkeyBech32InputTarget.value = this.pubkeyBech32 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (window.nostr) { |     if (window.nostr) { | ||||||
|       if (this.hasSetPubkeyTarget) { |       if (this.hasSetPubkeyTarget) { | ||||||
|         this.setPubkeyTarget.disabled = false |         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 () { |   get csrfToken () { | ||||||
|     const element = document.head.querySelector('meta[name="csrf-token"]') |     const element = document.head.querySelector('meta[name="csrf-token"]') | ||||||
|     return element.getAttribute("content") |     return element.getAttribute("content") | ||||||
|  | |||||||
| @ -1,3 +1,5 @@ | |||||||
|  | require 'nostr' | ||||||
|  | 
 | ||||||
| class User < ApplicationRecord | class User < ApplicationRecord | ||||||
|   include EmailValidatable |   include EmailValidatable | ||||||
| 
 | 
 | ||||||
| @ -185,6 +187,11 @@ class User < ApplicationRecord | |||||||
|     ldap.delete_attribute(dn,:service) |     ldap.delete_attribute(dn,:service) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   def nostr_pubkey_bech32 | ||||||
|  |     return nil unless nostr_pubkey.present? | ||||||
|  |     Nostr::PublicKey.new(nostr_pubkey).to_bech32 | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   private |   private | ||||||
| 
 | 
 | ||||||
|     def ldap |     def ldap | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ | |||||||
|        data-settings--nostr-pubkey-pubkey-hex-value="<%= current_user.nostr_pubkey %>"> |        data-settings--nostr-pubkey-pubkey-hex-value="<%= current_user.nostr_pubkey %>"> | ||||||
| 
 | 
 | ||||||
|     <p class="<%= current_user.nostr_pubkey.present? ? '' : 'hidden' %> mt-2 flex gap-1"> |     <p class="<%= current_user.nostr_pubkey.present? ? '' : 'hidden' %> mt-2 flex gap-1"> | ||||||
|       <input type="text" value="<%= current_user.nostr_pubkey %>" disabled |       <input type="text" value="<%= current_user.nostr_pubkey_bech32 %>" disabled | ||||||
|              data-settings--nostr-pubkey-target="pubkeyBech32Input" |              data-settings--nostr-pubkey-target="pubkeyBech32Input" | ||||||
|              name="nostr_public_key" class="relative grow" /> |              name="nostr_public_key" class="relative grow" /> | ||||||
|       <%= link_to nostr_pubkey_settings_path, |       <%= link_to nostr_pubkey_settings_path, | ||||||
|  | |||||||
| @ -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", to: "stimulus.min.js", preload: true | ||||||
| pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true | pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true | ||||||
| pin_all_from "app/javascript/controllers", under: "controllers" | pin_all_from "app/javascript/controllers", under: "controllers" | ||||||
| pin "bech32" # @2.0.0 |  | ||||||
| pin "tailwindcss-stimulus-components" # @4.0.3 | pin "tailwindcss-stimulus-components" # @4.0.3 | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ RSpec.describe 'Experimental Settings', type: :feature do | |||||||
|     scenario 'Remove nostr pubkey from account' do |     scenario 'Remove nostr pubkey from account' do | ||||||
|       visit setting_path(:experiments) |       visit setting_path(:experiments) | ||||||
|       expect(page).to have_field("nostr_public_key", |       expect(page).to have_field("nostr_public_key", | ||||||
|         with: "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3", |         with: "npub1qlsc3g0lsl8pw8230w8d9wm6xxcax3f6pkemz5measrmwfxjxteslf2hac", | ||||||
|         disabled: true) |         disabled: true) | ||||||
| 
 | 
 | ||||||
|       click_link "Remove" |       click_link "Remove" | ||||||
|  | |||||||
| @ -205,4 +205,14 @@ RSpec.describe User, type: :model do | |||||||
|       end |       end | ||||||
|     end |     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 | end | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								vendor/javascript/bech32.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/javascript/bech32.js
									
									
									
									
										vendored
									
									
								
							| @ -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<r.length;e++){const o=r.charAt(e);t[o]=e}function polymodStep(e){const r=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;t<e.length;++t){const o=e.charCodeAt(t);if(o<33||o>126)return"Invalid prefix ("+e+")";r=polymodStep(r)^o>>5}r=polymodStep(r);for(let t=0;t<e.length;++t){const o=e.charCodeAt(t);r=polymodStep(r)^31&o}return r}function convert(e,r,t,o){let n=0;let c=0;const s=(1<<t)-1;const f=[];for(let o=0;o<e.length;++o){n=n<<r|e[o];c+=r;while(c>=t){c-=t;f.push(n>>c&s)}}if(o)c>0&&f.push(n<<t-c&s);else{if(c>=r)return"Excess padding";if(n<<t-c&s)return"Non-zero padding"}return f}function toWords(e){return convert(e,8,5,true)}function fromWordsUnsafe(e){const r=convert(e,5,8,false);if(Array.isArray(r))return r}function fromWords(e){const r=convert(e,5,8,false);if(Array.isArray(r))return r;throw new Error(r)}function getLibraryFromEncoding(e){let o;o="bech32"===e?1:734539939;function encode(e,t,n){n=n||90;if(e.length+7+t.length>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<t.length;++e){const o=t[e];if(o>>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;++e){const r=i.charAt(e);const o=t[r];if(void 0===o)return"Unknown character "+r;d=polymodStep(d)^o;e+6>=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}; |  | ||||||
| 
 |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user