Skip to content

Instantly share code, notes, and snippets.

@Anderson-Juhasc
Created October 29, 2024 20:50
Show Gist options
  • Save Anderson-Juhasc/e78e1ff349eb4299328038eedd3fe3b2 to your computer and use it in GitHub Desktop.
Save Anderson-Juhasc/e78e1ff349eb4299328038eedd3fe3b2 to your computer and use it in GitHub Desktop.
Nostr NIP-07 with onAccountChanged
// based on: https://github.com/fiatjaf/nos2x/blob/master/extension/nostr-provider.js
window.nostr = {
_requests: {},
_pubkey: null,
_accountChangeCallback: null,
_monitoringInterval: null,
async getPublicKey() {
if (this._pubkey) return this._pubkey
this._pubkey = await this._call('getPublicKey', {})
return this._pubkey
},
async signEvent(event) {
return this._call('signEvent', {event})
},
async getRelays() {
return this._call('getRelays', {})
},
async onAccountChanged() {
return this._call('onAccountChanged', {})
},
nip04: {
async encrypt(peer, plaintext) {
return window.nostr._call('nip04.encrypt', {peer, plaintext})
},
async decrypt(peer, ciphertext) {
return window.nostr._call('nip04.decrypt', {peer, ciphertext})
}
},
nip44: {
async encrypt(peer, plaintext) {
return window.nostr._call('nip44.encrypt', {peer, plaintext})
},
async decrypt(peer, ciphertext) {
return window.nostr._call('nip44.decrypt', {peer, ciphertext})
}
},
onAccountChanged(callback) {
this._accountChangeCallback = callback;
// Start monitoring if a callback is registered
if (!this._monitoringInterval) {
this._monitoringInterval = setInterval(() => this._checkForAccountChange(), 1000);
}
},
async _checkForAccountChange() {
const storedPublicKey = await this._call('getPublicKey', {})
if (storedPublicKey !== this._pubkey) {
this._pubkey = storedPublicKey;
if (this._accountChangeCallback) {
this._accountChangeCallback(this._pubkey);
}
}
},
_call(type, params) {
let id = Math.random().toString().slice(-4)
console.log(
'%c[Nostrame:%c' +
id +
'%c]%c calling %c' +
type +
'%c with %c' +
JSON.stringify(params || {}),
'background-color:#f1b912;font-weight:bold;color:white',
'background-color:#f1b912;font-weight:bold;color:#a92727',
'background-color:#f1b912;color:white;font-weight:bold',
'color:auto',
'font-weight:bold;color:#08589d;font-family:monospace',
'color:auto',
'font-weight:bold;color:#90b12d;font-family:monospace'
)
return new Promise((resolve, reject) => {
this._requests[id] = {resolve, reject}
window.postMessage(
{
id,
ext: 'Nostrame',
type,
params
},
'*'
)
})
}
}
window.addEventListener('message', message => {
if (
!message.data ||
message.data.response === null ||
message.data.response === undefined ||
message.data.ext !== 'Nostrame' ||
!window.nostr._requests[message.data.id]
)
return
if (message.data.response.error) {
let error = new Error('Nostrame: ' + message.data.response.error.message)
error.stack = message.data.response.error.stack
window.nostr._requests[message.data.id].reject(error)
} else {
window.nostr._requests[message.data.id].resolve(message.data.response)
}
console.log(
'%c[Nostrame:%c' +
message.data.id +
'%c]%c result: %c' +
JSON.stringify(
message?.data?.response || message?.data?.response?.error?.message || {}
),
'background-color:#f1b912;font-weight:bold;color:white',
'background-color:#f1b912;font-weight:bold;color:#a92727',
'background-color:#f1b912;color:white;font-weight:bold',
'color:auto',
'font-weight:bold;color:#08589d'
)
delete window.nostr._requests[message.data.id]
})
// hack to replace nostr:nprofile.../etc links with something else
let replacing = null
document.addEventListener('mousedown', replaceNostrSchemeLink)
async function replaceNostrSchemeLink(e) {
if (e.target.tagName !== 'A' || !e.target.href.startsWith('nostr:')) return
if (replacing === false) return
let response = await window.nostr._call('replaceURL', {url: e.target.href})
if (response === false) {
replacing = false
return
}
e.target.href = response
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment