mirror of
https://github.com/styppo/hamstr.git
synced 2024-10-18 21:43:25 +00:00
allow signing manually with an external key.
This commit is contained in:
parent
46ab2566b0
commit
161941a9c5
@ -15,7 +15,7 @@
|
|||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"identicon.js": "^2.3.3",
|
"identicon.js": "^2.3.3",
|
||||||
"markdown-it": "^12.3.0",
|
"markdown-it": "^12.3.0",
|
||||||
"nostr-tools": "^0.18.0",
|
"nostr-tools": "^0.19.0",
|
||||||
"pouchdb-adapter-idb": "6",
|
"pouchdb-adapter-idb": "6",
|
||||||
"pouchdb-core": "6",
|
"pouchdb-core": "6",
|
||||||
"pouchdb-mapreduce": "6",
|
"pouchdb-mapreduce": "6",
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
unelevated
|
unelevated
|
||||||
type="submit"
|
type="submit"
|
||||||
color="primary"
|
color="primary"
|
||||||
:disable="!$store.state.keys.priv"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</q-form>
|
</q-form>
|
||||||
@ -48,9 +47,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
sendPost() {
|
async sendPost() {
|
||||||
this.$store.dispatch('sendPost', {message: this.text})
|
let ok = await this.$store.dispatch('sendPost', {message: this.text})
|
||||||
this.text = ''
|
if (ok) this.text = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,14 +10,7 @@
|
|||||||
</q-input>
|
</q-input>
|
||||||
|
|
||||||
<div class="flex justify-end mt-2">
|
<div class="flex justify-end mt-2">
|
||||||
<q-btn
|
<q-btn label="Reply" rounded unelevated type="submit" color="primary" />
|
||||||
:disable="!$store.state.keys.priv"
|
|
||||||
label="Reply"
|
|
||||||
rounded
|
|
||||||
unelevated
|
|
||||||
type="submit"
|
|
||||||
color="primary"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</q-form>
|
</q-form>
|
||||||
</template>
|
</template>
|
||||||
@ -39,7 +32,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
sendReply() {
|
async sendReply() {
|
||||||
// build tags
|
// build tags
|
||||||
let tags = []
|
let tags = []
|
||||||
|
|
||||||
@ -69,11 +62,12 @@ export default {
|
|||||||
// remove ourselves
|
// remove ourselves
|
||||||
tags = tags.filter(([_, v]) => v !== this.$store.state.keys.pub)
|
tags = tags.filter(([_, v]) => v !== this.$store.state.keys.pub)
|
||||||
|
|
||||||
this.$store.dispatch('sendPost', {
|
let ok = await this.$store.dispatch('sendPost', {
|
||||||
message: this.text,
|
message: this.text,
|
||||||
tags
|
tags
|
||||||
})
|
})
|
||||||
this.text = ''
|
|
||||||
|
if (ok) this.text = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,22 +221,21 @@
|
|||||||
<div class="text-lg text-bold tracking-wide leading-relaxed py-2">
|
<div class="text-lg text-bold tracking-wide leading-relaxed py-2">
|
||||||
Initial Key Setup
|
Initial Key Setup
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<div class="mb-2">
|
||||||
Type your mnemonic seed from a previous Nostr account or generate a
|
Type your private key from a previous Nostr account or generate a
|
||||||
new one.
|
new one.
|
||||||
</p>
|
</div>
|
||||||
<p>
|
<div>
|
||||||
You can also type a raw private key or just a public key for a
|
You can also type just a public key and later sign events manually
|
||||||
watch-only setup.
|
or using a Nostr-capable browser extension.
|
||||||
</p>
|
</div>
|
||||||
</q-card-section>
|
|
||||||
<q-card-section>
|
|
||||||
<q-form @submit="proceed">
|
<q-form @submit="proceed">
|
||||||
<q-input
|
<q-input
|
||||||
v-model="key"
|
v-model="key"
|
||||||
autogrow
|
autogrow
|
||||||
autofocus
|
autofocus
|
||||||
label="BIP39 Seed Words, private key or public key"
|
label="Private key or public key"
|
||||||
class="text-lg"
|
class="text-lg"
|
||||||
/>
|
/>
|
||||||
<q-toggle
|
<q-toggle
|
||||||
|
@ -103,23 +103,17 @@
|
|||||||
<div class="text-lg text-bold tracking-wide leading-relaxed py-2">
|
<div class="text-lg text-bold tracking-wide leading-relaxed py-2">
|
||||||
Your keys <q-icon name="vpn_key" />
|
Your keys <q-icon name="vpn_key" />
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p v-if="$store.state.keys.priv">
|
||||||
Make sure you back up your private key! <br />
|
Make sure you back up your private key!
|
||||||
<small
|
|
||||||
>Posts are published using your private key. Others can see your
|
|
||||||
posts or follow you using only your public key.</small
|
|
||||||
>
|
|
||||||
</p>
|
</p>
|
||||||
|
<p v-else>Your private key is not here!</p>
|
||||||
|
<div class="mt-1 text-xs">
|
||||||
|
Posts are published using your private key. Others can see your
|
||||||
|
posts or follow you using only your public key.
|
||||||
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<p>Seed Words:</p>
|
|
||||||
<q-input
|
|
||||||
v-model="$store.state.keys.mnemonic"
|
|
||||||
class="mb-2"
|
|
||||||
readonly
|
|
||||||
filled
|
|
||||||
/>
|
|
||||||
<p>Private Key:</p>
|
<p>Private Key:</p>
|
||||||
<q-input
|
<q-input
|
||||||
v-model="$store.state.keys.priv"
|
v-model="$store.state.keys.priv"
|
||||||
|
31
src/pool.js
31
src/pool.js
@ -1,5 +1,36 @@
|
|||||||
import {relayPool} from 'nostr-tools'
|
import {relayPool} from 'nostr-tools'
|
||||||
|
import {Dialog} from 'quasar'
|
||||||
|
|
||||||
export const pool = relayPool()
|
export const pool = relayPool()
|
||||||
|
|
||||||
pool.setPolicy('randomChoice', 3)
|
pool.setPolicy('randomChoice', 3)
|
||||||
|
|
||||||
|
// this will try to sign either with window.nostr or using a manual prompt
|
||||||
|
export async function signAsynchronously(event) {
|
||||||
|
if (window.nostr) {
|
||||||
|
return window.nostr.signEvent(event)
|
||||||
|
} else {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
Dialog.create({
|
||||||
|
class: 'px-6 py-1 overflow-hidden',
|
||||||
|
title: 'Sign this event manually',
|
||||||
|
message: `<pre class="font-mono">${JSON.stringify(
|
||||||
|
event,
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)}</pre>`,
|
||||||
|
html: true,
|
||||||
|
prompt: {
|
||||||
|
model: '',
|
||||||
|
type: 'text',
|
||||||
|
isValid: val => !!val.toLowerCase().match(/^[a-z0-9]{128}$/),
|
||||||
|
attrs: {autocomplete: 'off'},
|
||||||
|
label: 'Paste the signature here (as hex)'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.onOk(resolve)
|
||||||
|
.onCancel(() => reject('Canceled.'))
|
||||||
|
.onDismiss(() => reject('Canceled.'))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {encrypt} from 'nostr-tools/nip04'
|
import {encrypt} from 'nostr-tools/nip04'
|
||||||
import {Notify, LocalStorage} from 'quasar'
|
import {Notify, LocalStorage} from 'quasar'
|
||||||
|
|
||||||
import {pool} from '../pool'
|
import {pool, signAsynchronously} from '../pool'
|
||||||
import {dbSave, dbGetProfile, dbGetContactList} from '../db'
|
import {dbSave, dbGetProfile, dbGetContactList} from '../db'
|
||||||
|
|
||||||
export function initKeys(store, keys) {
|
export function initKeys(store, keys) {
|
||||||
@ -19,9 +19,11 @@ export async function launch(store) {
|
|||||||
store.commit('haveReadNotifications')
|
store.commit('haveReadNotifications')
|
||||||
}
|
}
|
||||||
|
|
||||||
// now we already have a key
|
// if we have already have a private key
|
||||||
if (store.state.keys.priv) {
|
if (store.state.keys.priv) {
|
||||||
pool.setPrivateKey(store.state.keys.priv)
|
pool.setPrivateKey(store.state.keys.priv)
|
||||||
|
} else {
|
||||||
|
pool.registerSigningFunction(signAsynchronously)
|
||||||
}
|
}
|
||||||
|
|
||||||
// translate localStorage into a kind3 event -- or load relays and following from event
|
// translate localStorage into a kind3 event -- or load relays and following from event
|
||||||
@ -138,15 +140,31 @@ export function restartMainSubscription(store) {
|
|||||||
export async function sendPost(store, {message, tags = [], kind = 1}) {
|
export async function sendPost(store, {message, tags = [], kind = 1}) {
|
||||||
if (message.length === 0) return
|
if (message.length === 0) return
|
||||||
|
|
||||||
let event = await pool.publish({
|
let event
|
||||||
|
try {
|
||||||
|
event = await pool.publish({
|
||||||
pubkey: store.state.keys.pub,
|
pubkey: store.state.keys.pub,
|
||||||
created_at: Math.floor(Date.now() / 1000),
|
created_at: Math.floor(Date.now() / 1000),
|
||||||
kind,
|
kind,
|
||||||
tags,
|
tags,
|
||||||
content: message
|
content: message
|
||||||
})
|
})
|
||||||
|
} catch (err) {
|
||||||
|
Notify.create({
|
||||||
|
message: `Did not publish: ${err}`,
|
||||||
|
color: 'red'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!event) {
|
||||||
|
// aborted
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
store.dispatch('addEvent', {event})
|
store.dispatch('addEvent', {event})
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setMetadata(store, metadata) {
|
export async function setMetadata(store, metadata) {
|
||||||
|
@ -20,7 +20,7 @@ export function setKeys(state, {mnemonic, priv, pub} = {}) {
|
|||||||
pub = getPublicKey(priv)
|
pub = getPublicKey(priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
state.keys = {mnemonic, priv, pub}
|
state.keys = {priv, pub}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setRelays(state, relays) {
|
export function setRelays(state, relays) {
|
||||||
|
@ -3,6 +3,7 @@ import {LocalStorage} from 'quasar'
|
|||||||
export default function () {
|
export default function () {
|
||||||
return {
|
return {
|
||||||
keys: LocalStorage.getItem('keys') || {pub: '00'}, // { mnemonic, priv, pub }
|
keys: LocalStorage.getItem('keys') || {pub: '00'}, // { mnemonic, priv, pub }
|
||||||
|
|
||||||
relays: {
|
relays: {
|
||||||
// 'wss://nostr.rocks': {read: true, write: true},
|
// 'wss://nostr.rocks': {read: true, write: true},
|
||||||
'wss://relayer.fiatjaf.com': {read: true, write: true},
|
'wss://relayer.fiatjaf.com': {read: true, write: true},
|
||||||
|
@ -4769,10 +4769,10 @@ normalize-url@^6.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
|
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
|
||||||
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
|
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
|
||||||
|
|
||||||
nostr-tools@^0.18.0:
|
nostr-tools@^0.19.0:
|
||||||
version "0.18.0"
|
version "0.19.0"
|
||||||
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-0.18.0.tgz#d5c76ecd2ea6728a772de5daa5ab5d8110f3425c"
|
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-0.19.0.tgz#3e086f4a1715607d8917912f56a16866a115efec"
|
||||||
integrity sha512-NOAC7JhNrAtFnEsr4vEG3PzSzhAcChzXr0SCcfrlFbXcwIFKHcrBGZ4K6qmhJPGpVvhuXwquixG3KlfMIoqc5g==
|
integrity sha512-kn7+gy+Ncrf7WkIN/OTuNu/EZtfK2hVLQZw9CQOVcngeF5nlqMRVrgMQBo2CkrkFFV5G5tS71lH4imtiklh13g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@noble/hashes" "^0.5.7"
|
"@noble/hashes" "^0.5.7"
|
||||||
"@noble/secp256k1" "^1.3.0"
|
"@noble/secp256k1" "^1.3.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user