provider nprofile
This commit is contained in:
parent
602146fa2c
commit
2f4713ebae
8 changed files with 121 additions and 19 deletions
73
decode.js
Executable file
73
decode.js
Executable file
|
|
@ -0,0 +1,73 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import { decodeBech32, nip19 } from '@shocknet/clink-sdk'
|
||||||
|
|
||||||
|
const nip19String = process.argv[2]
|
||||||
|
|
||||||
|
if (!nip19String) {
|
||||||
|
console.error('Usage: node decode.js <nip19_string>')
|
||||||
|
console.error('Example: node decode.js nprofile1qyd8wumn8ghj7um5wfn8y7fwwd5x7cmt9ehx2arhdaexkqpqwmk5tuqvafa6ckwc6zmaypyy3af3n4aeds2ql7m0ew42kzsn638q9s9z8p')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Check prefix to determine which decoder to use
|
||||||
|
const prefix = nip19String.split('1')[0]
|
||||||
|
const decoded = (prefix === 'noffer' || prefix === 'ndebit' || prefix === 'nmanage')
|
||||||
|
? decodeBech32(nip19String)
|
||||||
|
: nip19.decode(nip19String)
|
||||||
|
|
||||||
|
console.log('\nDecoded:')
|
||||||
|
console.log('Type:', decoded.type)
|
||||||
|
console.log('\nData:')
|
||||||
|
console.log(JSON.stringify(decoded.data, null, 2))
|
||||||
|
|
||||||
|
if (decoded.type === 'nprofile') {
|
||||||
|
console.log('\nDetails:')
|
||||||
|
console.log(' Pubkey:', decoded.data.pubkey)
|
||||||
|
if (decoded.data.relays) {
|
||||||
|
console.log(' Relays:')
|
||||||
|
decoded.data.relays.forEach((relay, i) => {
|
||||||
|
console.log(` ${i + 1}. ${relay}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (decoded.type === 'npub') {
|
||||||
|
console.log('\nDetails:')
|
||||||
|
console.log(' Pubkey:', decoded.data)
|
||||||
|
} else if (decoded.type === 'nsec') {
|
||||||
|
console.log('\nDetails:')
|
||||||
|
console.log(' Private Key:', decoded.data)
|
||||||
|
} else if (decoded.type === 'note') {
|
||||||
|
console.log('\nDetails:')
|
||||||
|
console.log(' Event ID:', decoded.data)
|
||||||
|
} else if (decoded.type === 'noffer') {
|
||||||
|
console.log('\nDetails:')
|
||||||
|
console.log(' Pubkey:', decoded.data.pubkey)
|
||||||
|
console.log(' Offer:', decoded.data.offer)
|
||||||
|
if (decoded.data.relay) {
|
||||||
|
console.log(' Relay:', decoded.data.relay)
|
||||||
|
}
|
||||||
|
if (decoded.data.priceType) {
|
||||||
|
console.log(' Price Type:', decoded.data.priceType)
|
||||||
|
}
|
||||||
|
} else if (decoded.type === 'ndebit') {
|
||||||
|
console.log('\nDetails:')
|
||||||
|
console.log(' Pubkey:', decoded.data.pubkey)
|
||||||
|
console.log(' Pointer:', decoded.data.pointer)
|
||||||
|
if (decoded.data.relay) {
|
||||||
|
console.log(' Relay:', decoded.data.relay)
|
||||||
|
}
|
||||||
|
} else if (decoded.type === 'nmanage') {
|
||||||
|
console.log('\nDetails:')
|
||||||
|
console.log(' Pubkey:', decoded.data.pubkey)
|
||||||
|
console.log(' Pointer:', decoded.data.pointer)
|
||||||
|
if (decoded.data.relay) {
|
||||||
|
console.log(' Relay:', decoded.data.relay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error decoding bech32 string:', error.message)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -16,11 +16,11 @@
|
||||||
|
|
||||||
#BOOTSTRAP_PEER
|
#BOOTSTRAP_PEER
|
||||||
# A trusted peer that will hold a node-level account until channel automation becomes affordable
|
# A trusted peer that will hold a node-level account until channel automation becomes affordable
|
||||||
# The developer is used by default or you may specify your own
|
# The provider pubkey is extracted from PROVIDER_NPROFILE (nprofile contains both pubkey and relay URL)
|
||||||
# To disable this feature entirely overwrite the env with "null"
|
# The developers node is used by default, or you may specify another.
|
||||||
#LIQUIDITY_PROVIDER_PUB=null
|
# To disable this feature entirely set DISABLE_LIQUIDITY_PROVIDER=true
|
||||||
#DISABLE_LIQUIDITY_PROVIDER=false
|
#DISABLE_LIQUIDITY_PROVIDER=false
|
||||||
#PROVIDER_RELAY_URL=
|
#PROVIDER_NPROFILE=nprofile1qyd8wumn8ghj7um5wfn8y7fwwd5x7cmt9ehx2arhdaexkqpqwmk5tuqvafa6ckwc6zmaypyy3af3n4aeds2ql7m0ew42kzsn638q9s9z8p
|
||||||
|
|
||||||
#SWAPS
|
#SWAPS
|
||||||
#BOLTZ_HTTP_URL=
|
#BOLTZ_HTTP_URL=
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ const start = async () => {
|
||||||
name: app.name,
|
name: app.name,
|
||||||
provider: app.publicKey === liquidityProviderInfo.publicKey ? {
|
provider: app.publicKey === liquidityProviderInfo.publicKey ? {
|
||||||
clientId: liquidityProviderInfo.clientId,
|
clientId: liquidityProviderInfo.clientId,
|
||||||
pubDestination: settingsManager.getSettings().liquiditySettings.liquidityProviderPub,
|
pubkey: settingsManager.getSettings().liquiditySettings.liquidityProviderPub,
|
||||||
relayUrl: settingsManager.getSettings().liquiditySettings.providerRelayUrl || relays[0]
|
relayUrl: settingsManager.getSettings().liquiditySettings.providerRelayUrl
|
||||||
} : undefined
|
} : undefined
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,8 @@ const start = async () => {
|
||||||
name: app.name,
|
name: app.name,
|
||||||
provider: app.publicKey === liquidityProviderInfo.publicKey ? {
|
provider: app.publicKey === liquidityProviderInfo.publicKey ? {
|
||||||
clientId: liquidityProviderInfo.clientId,
|
clientId: liquidityProviderInfo.clientId,
|
||||||
pubDestination: settingsManager.getSettings().liquiditySettings.liquidityProviderPub,
|
pubkey: settingsManager.getSettings().liquiditySettings.liquidityProviderPub,
|
||||||
relayUrl: settingsManager.getSettings().liquiditySettings.providerRelayUrl || relays[0]
|
relayUrl: settingsManager.getSettings().liquiditySettings.providerRelayUrl
|
||||||
} : undefined
|
} : undefined
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -486,8 +486,8 @@ export default class {
|
||||||
name: app.name,
|
name: app.name,
|
||||||
provider: app.nostr_public_key === liquidityProviderInfo.publicKey ? {
|
provider: app.nostr_public_key === liquidityProviderInfo.publicKey ? {
|
||||||
clientId: liquidityProviderInfo.clientId,
|
clientId: liquidityProviderInfo.clientId,
|
||||||
pubDestination: this.settings.getSettings().liquiditySettings.liquidityProviderPub,
|
pubkey: this.settings.getSettings().liquiditySettings.liquidityProviderPub,
|
||||||
relayUrl: this.settings.getSettings().liquiditySettings.providerRelayUrl || relays[0]
|
relayUrl: this.settings.getSettings().liquiditySettings.providerRelayUrl
|
||||||
} : undefined
|
} : undefined
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -298,6 +298,7 @@ export class LiquidityProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onBeaconEvent = async (beaconData: { content: string, pub: string }) => {
|
onBeaconEvent = async (beaconData: { content: string, pub: string }) => {
|
||||||
|
this.log("received beacon event from", beaconData.pub, "expected", this.pubDestination)
|
||||||
if (beaconData.pub !== this.pubDestination) {
|
if (beaconData.pub !== this.pubDestination) {
|
||||||
this.log(ERROR, "got beacon from invalid pub", beaconData.pub, this.pubDestination)
|
this.log(ERROR, "got beacon from invalid pub", beaconData.pub, this.pubDestination)
|
||||||
return
|
return
|
||||||
|
|
@ -312,10 +313,13 @@ export class LiquidityProvider {
|
||||||
this.log(ERROR, "got beacon from invalid type", beacon.type)
|
this.log(ERROR, "got beacon from invalid type", beacon.type)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
this.log("valid beacon received, updating ready state")
|
||||||
this.lastSeenBeacon = Date.now()
|
this.lastSeenBeacon = Date.now()
|
||||||
|
this.ready = true
|
||||||
if (beacon.fees) {
|
if (beacon.fees) {
|
||||||
this.feesCache = beacon.fees
|
this.feesCache = beacon.fees
|
||||||
}
|
}
|
||||||
|
this.queue.forEach(q => q('ready'))
|
||||||
}
|
}
|
||||||
|
|
||||||
onEvent = async (res: { requestId: string }, fromPub: string) => {
|
onEvent = async (res: { requestId: string }, fromPub: string) => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { EnvCacher, EnvMustBeNonEmptyString, EnvMustBeInteger, chooseEnv, chooseEnvBool, chooseEnvInt } from '../helpers/envParser.js'
|
import { EnvCacher, EnvMustBeNonEmptyString, EnvMustBeInteger, chooseEnv, chooseEnvBool, chooseEnvInt } from '../helpers/envParser.js'
|
||||||
import os from 'os'
|
import os from 'os'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import { nip19 } from '@shocknet/clink-sdk'
|
||||||
|
|
||||||
export type ServiceFeeSettings = {
|
export type ServiceFeeSettings = {
|
||||||
serviceFee: number
|
serviceFee: number
|
||||||
|
|
@ -169,11 +170,32 @@ export type LiquiditySettings = {
|
||||||
providerRelayUrl: string
|
providerRelayUrl: string
|
||||||
}
|
}
|
||||||
export const LoadLiquiditySettingsFromEnv = (dbEnv: Record<string, string | undefined>, addToDb?: EnvCacher): LiquiditySettings => {
|
export const LoadLiquiditySettingsFromEnv = (dbEnv: Record<string, string | undefined>, addToDb?: EnvCacher): LiquiditySettings => {
|
||||||
//const liquidityProviderPub = process.env.LIQUIDITY_PROVIDER_PUB === "null" ? "" : (process.env.LIQUIDITY_PROVIDER_PUB || "76ed45f00cea7bac59d8d0b7d204848f5319d7b96c140ffb6fcbaaab0a13d44e")
|
const providerNprofile = chooseEnv("PROVIDER_NPROFILE", dbEnv, "nprofile1qyd8wumn8ghj7um5wfn8y7fwwd5x7cmt9ehx2arhdaexkqpqwmk5tuqvafa6ckwc6zmaypyy3af3n4aeds2ql7m0ew42kzsn638q9s9z8p", addToDb)
|
||||||
const liquidityProviderPub = chooseEnv("LIQUIDITY_PROVIDER_PUB", dbEnv, "76ed45f00cea7bac59d8d0b7d204848f5319d7b96c140ffb6fcbaaab0a13d44e", addToDb)
|
|
||||||
|
// Decode nprofile to extract pubkey and relay URL
|
||||||
|
let liquidityProviderPub = ""
|
||||||
|
let providerRelayUrl = ""
|
||||||
|
if (providerNprofile) {
|
||||||
|
try {
|
||||||
|
const decoded = nip19.decode(providerNprofile)
|
||||||
|
if (decoded.type === 'nprofile') {
|
||||||
|
liquidityProviderPub = decoded.data.pubkey
|
||||||
|
if (decoded.data.relays && decoded.data.relays.length > 0) {
|
||||||
|
providerRelayUrl = decoded.data.relays[0]
|
||||||
|
} else {
|
||||||
|
throw new Error("PROVIDER_NPROFILE must contain at least one relay")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error("PROVIDER_NPROFILE must be a valid nprofile")
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Failed to decode PROVIDER_NPROFILE as nprofile: ${e}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const disableLiquidityProvider = chooseEnvBool("DISABLE_LIQUIDITY_PROVIDER", dbEnv, false, addToDb) || liquidityProviderPub === "null"
|
const disableLiquidityProvider = chooseEnvBool("DISABLE_LIQUIDITY_PROVIDER", dbEnv, false, addToDb) || liquidityProviderPub === "null"
|
||||||
const useOnlyLiquidityProvider = chooseEnvBool("USE_ONLY_LIQUIDITY_PROVIDER", dbEnv, false, addToDb)
|
const useOnlyLiquidityProvider = chooseEnvBool("USE_ONLY_LIQUIDITY_PROVIDER", dbEnv, false, addToDb)
|
||||||
const providerRelayUrl = chooseEnv("PROVIDER_RELAY_URL", dbEnv, "", addToDb)
|
|
||||||
return { liquidityProviderPub, useOnlyLiquidityProvider, disableLiquidityProvider, providerRelayUrl }
|
return { liquidityProviderPub, useOnlyLiquidityProvider, disableLiquidityProvider, providerRelayUrl }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export type SendData = SendDataContent | SendDataEvent
|
||||||
export type SendInitiator = { type: 'app', appId: string } | { type: 'client', clientId: string }
|
export type SendInitiator = { type: 'app', appId: string } | { type: 'client', clientId: string }
|
||||||
export type NostrSend = (initiator: SendInitiator, data: SendData, relays?: string[] | undefined) => void
|
export type NostrSend = (initiator: SendInitiator, data: SendData, relays?: string[] | undefined) => void
|
||||||
|
|
||||||
export type LinkedProviderInfo = { pubDestination: string, clientId: string, relayUrl: string }
|
export type LinkedProviderInfo = { pubkey: string, clientId: string, relayUrl: string }
|
||||||
export type AppInfo = { appId: string, publicKey: string, privateKey: string, name: string, provider?: LinkedProviderInfo }
|
export type AppInfo = { appId: string, publicKey: string, privateKey: string, name: string, provider?: LinkedProviderInfo }
|
||||||
// export type ClientInfo = { clientId: string, publicKey: string, privateKey: string, name: string }
|
// export type ClientInfo = { clientId: string, publicKey: string, privateKey: string, name: string }
|
||||||
export type NostrSettings = {
|
export type NostrSettings = {
|
||||||
|
|
@ -122,9 +122,12 @@ export class NostrPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
private validateEvent(e: Event, relay: RelayConnection): { type: 'event', pub: string, app: AppInfo } | { type: 'beacon', content: string, pub: string } | null {
|
private validateEvent(e: Event, relay: RelayConnection): { type: 'event', pub: string, app: AppInfo } | { type: 'beacon', content: string, pub: string } | null {
|
||||||
if (e.kind === 30078 && this.providerInfo && relay.isProviderRelay() && e.pubkey === this.providerInfo.pubDestination) {
|
if (e.kind === 30078 && this.providerInfo && e.pubkey === this.providerInfo.pubkey) {
|
||||||
|
// Accept beacons from provider relay (which may also be a service relay)
|
||||||
|
if (relay.isProviderRelay()) {
|
||||||
return { type: 'beacon', content: e.content, pub: e.pubkey }
|
return { type: 'beacon', content: e.content, pub: e.pubkey }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!actionKinds.includes(e.kind) || !e.pubkey) {
|
if (!actionKinds.includes(e.kind) || !e.pubkey) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
@ -268,7 +271,7 @@ const processApps = (settings: NostrSettings) => {
|
||||||
const filters = [getServiceFilter(apps)]
|
const filters = [getServiceFilter(apps)]
|
||||||
if (providerInfo && providerInfo.relayUrl === r) {
|
if (providerInfo && providerInfo.relayUrl === r) {
|
||||||
providerAssigned = true
|
providerAssigned = true
|
||||||
filters.push(getBeaconFilter(providerInfo.pubDestination))
|
filters.push(getBeaconFilter(providerInfo.pubkey))
|
||||||
}
|
}
|
||||||
rSettings.push({
|
rSettings.push({
|
||||||
relayUrl: r,
|
relayUrl: r,
|
||||||
|
|
@ -283,8 +286,8 @@ const processApps = (settings: NostrSettings) => {
|
||||||
providerRelay: true,
|
providerRelay: true,
|
||||||
serviceRelay: false,
|
serviceRelay: false,
|
||||||
filters: [
|
filters: [
|
||||||
getProviderFilter(providerInfo.appPub, providerInfo.pubDestination),
|
getProviderFilter(providerInfo.appPub, providerInfo.pubkey),
|
||||||
getBeaconFilter(providerInfo.pubDestination),
|
getBeaconFilter(providerInfo.pubkey),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue