default cb url for user
This commit is contained in:
parent
19ee91cd5f
commit
61da2eea77
19 changed files with 237 additions and 13 deletions
|
|
@ -26,13 +26,14 @@ import { PaymentIndex1721760297610 } from './build/src/services/storage/migratio
|
||||||
import { DebitAccess1726496225078 } from './build/src/services/storage/migrations/1726496225078-debit_access.js'
|
import { DebitAccess1726496225078 } from './build/src/services/storage/migrations/1726496225078-debit_access.js'
|
||||||
import { DebitAccessFixes1726685229264 } from './build/src/services/storage/migrations/1726685229264-debit_access_fixes.js'
|
import { DebitAccessFixes1726685229264 } from './build/src/services/storage/migrations/1726685229264-debit_access_fixes.js'
|
||||||
import { DebitToPub1727105758354 } from './build/src/services/storage/migrations/1727105758354-debit_to_pub.js'
|
import { DebitToPub1727105758354 } from './build/src/services/storage/migrations/1727105758354-debit_to_pub.js'
|
||||||
|
import { UserCbUrl1727112281043 } from './build/src/services/storage/migrations/1727112281043-user_cb_url.js'
|
||||||
export default new DataSource({
|
export default new DataSource({
|
||||||
type: "sqlite",
|
type: "sqlite",
|
||||||
database: "db.sqlite",
|
database: "db.sqlite",
|
||||||
// logging: true,
|
// logging: true,
|
||||||
migrations: [Initial1703170309875, LspOrder1718387847693, LiquidityProvider1719335699480, LndNodeInfo1720187506189, CreateInviteTokenTable1721751414878, PaymentIndex1721760297610, DebitAccess1726496225078, DebitAccessFixes1726685229264, DebitToPub1727105758354],
|
migrations: [Initial1703170309875, LspOrder1718387847693, LiquidityProvider1719335699480, LndNodeInfo1720187506189, CreateInviteTokenTable1721751414878, PaymentIndex1721760297610, DebitAccess1726496225078, DebitAccessFixes1726685229264, DebitToPub1727105758354, UserCbUrl1727112281043],
|
||||||
entities: [User, UserReceivingInvoice, UserReceivingAddress, AddressReceivingTransaction, UserInvoicePayment, UserTransactionPayment,
|
entities: [User, UserReceivingInvoice, UserReceivingAddress, AddressReceivingTransaction, UserInvoicePayment, UserTransactionPayment,
|
||||||
UserBasicAuth, UserEphemeralKey, Product, UserToUserPayment, Application, ApplicationUser, UserToUserPayment, LspOrder, LndNodeInfo, TrackedProvider, InviteToken, DebitAccess],
|
UserBasicAuth, UserEphemeralKey, Product, UserToUserPayment, Application, ApplicationUser, UserToUserPayment, LspOrder, LndNodeInfo, TrackedProvider, InviteToken, DebitAccess],
|
||||||
// synchronize: true,
|
// synchronize: true,
|
||||||
})
|
})
|
||||||
//npx typeorm migration:generate ./src/services/storage/migrations/debit_to_pub -d ./datasource.js
|
//npx typeorm migration:generate ./src/services/storage/migrations/usert_cb_url -d ./datasource.js
|
||||||
|
|
@ -195,6 +195,11 @@ The nostr server will send back a message response, and inside the body there wi
|
||||||
- input: [DebitOperation](#DebitOperation)
|
- input: [DebitOperation](#DebitOperation)
|
||||||
- This methods has an __empty__ __response__ body
|
- This methods has an __empty__ __response__ body
|
||||||
|
|
||||||
|
- UpdateCallbackUrl
|
||||||
|
- auth type: __User__
|
||||||
|
- input: [CallbackUrl](#CallbackUrl)
|
||||||
|
- output: [CallbackUrl](#CallbackUrl)
|
||||||
|
|
||||||
- UseInviteLink
|
- UseInviteLink
|
||||||
- auth type: __GuestWithPub__
|
- auth type: __GuestWithPub__
|
||||||
- input: [UseInviteLinkRequest](#UseInviteLinkRequest)
|
- input: [UseInviteLinkRequest](#UseInviteLinkRequest)
|
||||||
|
|
@ -654,6 +659,13 @@ The nostr server will send back a message response, and inside the body there wi
|
||||||
- input: [SetMockInvoiceAsPaidRequest](#SetMockInvoiceAsPaidRequest)
|
- input: [SetMockInvoiceAsPaidRequest](#SetMockInvoiceAsPaidRequest)
|
||||||
- This methods has an __empty__ __response__ body
|
- This methods has an __empty__ __response__ body
|
||||||
|
|
||||||
|
- UpdateCallbackUrl
|
||||||
|
- auth type: __User__
|
||||||
|
- http method: __post__
|
||||||
|
- http route: __/api/user/cb/update__
|
||||||
|
- input: [CallbackUrl](#CallbackUrl)
|
||||||
|
- output: [CallbackUrl](#CallbackUrl)
|
||||||
|
|
||||||
- UseInviteLink
|
- UseInviteLink
|
||||||
- auth type: __GuestWithPub__
|
- auth type: __GuestWithPub__
|
||||||
- http method: __post__
|
- http method: __post__
|
||||||
|
|
@ -748,6 +760,9 @@ The nostr server will send back a message response, and inside the body there wi
|
||||||
- __nostr_pub__: _string_
|
- __nostr_pub__: _string_
|
||||||
- __user_identifier__: _string_
|
- __user_identifier__: _string_
|
||||||
|
|
||||||
|
### CallbackUrl
|
||||||
|
- __url__: _string_
|
||||||
|
|
||||||
### ClosedChannel
|
### ClosedChannel
|
||||||
- __capacity__: _number_
|
- __capacity__: _number_
|
||||||
- __channel_id__: _string_
|
- __channel_id__: _string_
|
||||||
|
|
@ -1055,6 +1070,7 @@ The nostr server will send back a message response, and inside the body there wi
|
||||||
|
|
||||||
### UserInfo
|
### UserInfo
|
||||||
- __balance__: _number_
|
- __balance__: _number_
|
||||||
|
- __callback_url__: _string_
|
||||||
- __max_withdrawable__: _number_
|
- __max_withdrawable__: _number_
|
||||||
- __ndebit__: _string_
|
- __ndebit__: _string_
|
||||||
- __network_max_fee_bps__: _number_
|
- __network_max_fee_bps__: _number_
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ type Client struct {
|
||||||
SetMockAppBalance func(req SetMockAppBalanceRequest) error
|
SetMockAppBalance func(req SetMockAppBalanceRequest) error
|
||||||
SetMockAppUserBalance func(req SetMockAppUserBalanceRequest) error
|
SetMockAppUserBalance func(req SetMockAppUserBalanceRequest) error
|
||||||
SetMockInvoiceAsPaid func(req SetMockInvoiceAsPaidRequest) error
|
SetMockInvoiceAsPaid func(req SetMockInvoiceAsPaidRequest) error
|
||||||
|
UpdateCallbackUrl func(req CallbackUrl) (*CallbackUrl, error)
|
||||||
UseInviteLink func(req UseInviteLinkRequest) error
|
UseInviteLink func(req UseInviteLinkRequest) error
|
||||||
UserHealth func() error
|
UserHealth func() error
|
||||||
}
|
}
|
||||||
|
|
@ -1527,6 +1528,35 @@ func NewClient(params ClientParams) *Client {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
UpdateCallbackUrl: func(req CallbackUrl) (*CallbackUrl, error) {
|
||||||
|
auth, err := params.RetrieveUserAuth()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
finalRoute := "/api/user/cb/update"
|
||||||
|
body, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resBody, err := doPostRequest(params.BaseURL+finalRoute, body, auth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result := ResultError{}
|
||||||
|
err = json.Unmarshal(resBody, &result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if result.Status == "ERROR" {
|
||||||
|
return nil, fmt.Errorf(result.Reason)
|
||||||
|
}
|
||||||
|
res := CallbackUrl{}
|
||||||
|
err = json.Unmarshal(resBody, &res)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &res, nil
|
||||||
|
},
|
||||||
UseInviteLink: func(req UseInviteLinkRequest) error {
|
UseInviteLink: func(req UseInviteLinkRequest) error {
|
||||||
auth, err := params.RetrieveGuestWithPubAuth()
|
auth, err := params.RetrieveGuestWithPubAuth()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,9 @@ type BannedAppUser struct {
|
||||||
Nostr_pub string `json:"nostr_pub"`
|
Nostr_pub string `json:"nostr_pub"`
|
||||||
User_identifier string `json:"user_identifier"`
|
User_identifier string `json:"user_identifier"`
|
||||||
}
|
}
|
||||||
|
type CallbackUrl struct {
|
||||||
|
Url string `json:"url"`
|
||||||
|
}
|
||||||
type ClosedChannel struct {
|
type ClosedChannel struct {
|
||||||
Capacity int64 `json:"capacity"`
|
Capacity int64 `json:"capacity"`
|
||||||
Channel_id string `json:"channel_id"`
|
Channel_id string `json:"channel_id"`
|
||||||
|
|
@ -457,6 +460,7 @@ type UseInviteLinkRequest struct {
|
||||||
}
|
}
|
||||||
type UserInfo struct {
|
type UserInfo struct {
|
||||||
Balance int64 `json:"balance"`
|
Balance int64 `json:"balance"`
|
||||||
|
Callback_url string `json:"callback_url"`
|
||||||
Max_withdrawable int64 `json:"max_withdrawable"`
|
Max_withdrawable int64 `json:"max_withdrawable"`
|
||||||
Ndebit string `json:"ndebit"`
|
Ndebit string `json:"ndebit"`
|
||||||
Network_max_fee_bps int64 `json:"network_max_fee_bps"`
|
Network_max_fee_bps int64 `json:"network_max_fee_bps"`
|
||||||
|
|
|
||||||
|
|
@ -469,6 +469,18 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
|
||||||
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
|
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case 'UpdateCallbackUrl':
|
||||||
|
if (!methods.UpdateCallbackUrl) {
|
||||||
|
throw new Error('method UpdateCallbackUrl not found' )
|
||||||
|
} else {
|
||||||
|
const error = Types.CallbackUrlValidate(operation.req)
|
||||||
|
opStats.validate = process.hrtime.bigint()
|
||||||
|
if (error !== null) throw error
|
||||||
|
const res = await methods.UpdateCallbackUrl({...operation, ctx}); responses.push({ status: 'OK', ...res })
|
||||||
|
opStats.handle = process.hrtime.bigint()
|
||||||
|
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
|
||||||
|
}
|
||||||
|
break
|
||||||
case 'UserHealth':
|
case 'UserHealth':
|
||||||
if (!methods.UserHealth) {
|
if (!methods.UserHealth) {
|
||||||
throw new Error('method UserHealth not found' )
|
throw new Error('method UserHealth not found' )
|
||||||
|
|
@ -1387,6 +1399,28 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
|
||||||
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
|
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
|
||||||
} catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
|
} catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
|
||||||
})
|
})
|
||||||
|
if (!opts.allowNotImplementedMethods && !methods.UpdateCallbackUrl) throw new Error('method: UpdateCallbackUrl is not implemented')
|
||||||
|
app.post('/api/user/cb/update', async (req, res) => {
|
||||||
|
const info: Types.RequestInfo = { rpcName: 'UpdateCallbackUrl', batch: false, nostr: false, batchSize: 0}
|
||||||
|
const stats: Types.RequestStats = { startMs:req.startTimeMs || 0, start:req.startTime || 0n, parse: process.hrtime.bigint(), guard: 0n, validate: 0n, handle: 0n }
|
||||||
|
let authCtx: Types.AuthContext = {}
|
||||||
|
try {
|
||||||
|
if (!methods.UpdateCallbackUrl) throw new Error('method: UpdateCallbackUrl is not implemented')
|
||||||
|
const authContext = await opts.UserAuthGuard(req.headers['authorization'])
|
||||||
|
authCtx = authContext
|
||||||
|
stats.guard = process.hrtime.bigint()
|
||||||
|
const request = req.body
|
||||||
|
const error = Types.CallbackUrlValidate(request)
|
||||||
|
stats.validate = process.hrtime.bigint()
|
||||||
|
if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authContext }, opts.metricsCallback)
|
||||||
|
const query = req.query
|
||||||
|
const params = req.params
|
||||||
|
const response = await methods.UpdateCallbackUrl({rpcName:'UpdateCallbackUrl', ctx:authContext , req: request})
|
||||||
|
stats.handle = process.hrtime.bigint()
|
||||||
|
res.json({status: 'OK', ...response})
|
||||||
|
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
|
||||||
|
} catch (ex) { const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
|
||||||
|
})
|
||||||
if (!opts.allowNotImplementedMethods && !methods.UseInviteLink) throw new Error('method: UseInviteLink is not implemented')
|
if (!opts.allowNotImplementedMethods && !methods.UseInviteLink) throw new Error('method: UseInviteLink is not implemented')
|
||||||
app.post('/api/guest/invite', async (req, res) => {
|
app.post('/api/guest/invite', async (req, res) => {
|
||||||
const info: Types.RequestInfo = { rpcName: 'UseInviteLink', batch: false, nostr: false, batchSize: 0}
|
const info: Types.RequestInfo = { rpcName: 'UseInviteLink', batch: false, nostr: false, batchSize: 0}
|
||||||
|
|
|
||||||
|
|
@ -735,6 +735,20 @@ export default (params: ClientParams) => ({
|
||||||
}
|
}
|
||||||
return { status: 'ERROR', reason: 'invalid response' }
|
return { status: 'ERROR', reason: 'invalid response' }
|
||||||
},
|
},
|
||||||
|
UpdateCallbackUrl: async (request: Types.CallbackUrl): Promise<ResultError | ({ status: 'OK' }& Types.CallbackUrl)> => {
|
||||||
|
const auth = await params.retrieveUserAuth()
|
||||||
|
if (auth === null) throw new Error('retrieveUserAuth() returned null')
|
||||||
|
let finalRoute = '/api/user/cb/update'
|
||||||
|
const { data } = await axios.post(params.baseUrl + finalRoute, request, { headers: { 'authorization': auth } })
|
||||||
|
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
|
||||||
|
if (data.status === 'OK') {
|
||||||
|
const result = data
|
||||||
|
if(!params.checkResult) return { status: 'OK', ...result }
|
||||||
|
const error = Types.CallbackUrlValidate(result)
|
||||||
|
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
|
||||||
|
}
|
||||||
|
return { status: 'ERROR', reason: 'invalid response' }
|
||||||
|
},
|
||||||
UseInviteLink: async (request: Types.UseInviteLinkRequest): Promise<ResultError | ({ status: 'OK' })> => {
|
UseInviteLink: async (request: Types.UseInviteLinkRequest): Promise<ResultError | ({ status: 'OK' })> => {
|
||||||
const auth = await params.retrieveGuestWithPubAuth()
|
const auth = await params.retrieveGuestWithPubAuth()
|
||||||
if (auth === null) throw new Error('retrieveGuestWithPubAuth() returned null')
|
if (auth === null) throw new Error('retrieveGuestWithPubAuth() returned null')
|
||||||
|
|
|
||||||
|
|
@ -528,6 +528,21 @@ export default (params: NostrClientParams, send: (to:string, message: NostrRequ
|
||||||
}
|
}
|
||||||
return { status: 'ERROR', reason: 'invalid response' }
|
return { status: 'ERROR', reason: 'invalid response' }
|
||||||
},
|
},
|
||||||
|
UpdateCallbackUrl: async (request: Types.CallbackUrl): Promise<ResultError | ({ status: 'OK' }& Types.CallbackUrl)> => {
|
||||||
|
const auth = await params.retrieveNostrUserAuth()
|
||||||
|
if (auth === null) throw new Error('retrieveNostrUserAuth() returned null')
|
||||||
|
const nostrRequest: NostrRequest = {}
|
||||||
|
nostrRequest.body = request
|
||||||
|
const data = await send(params.pubDestination, {rpcName:'UpdateCallbackUrl',authIdentifier:auth, ...nostrRequest })
|
||||||
|
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
|
||||||
|
if (data.status === 'OK') {
|
||||||
|
const result = data
|
||||||
|
if(!params.checkResult) return { status: 'OK', ...result }
|
||||||
|
const error = Types.CallbackUrlValidate(result)
|
||||||
|
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
|
||||||
|
}
|
||||||
|
return { status: 'ERROR', reason: 'invalid response' }
|
||||||
|
},
|
||||||
UseInviteLink: async (request: Types.UseInviteLinkRequest): Promise<ResultError | ({ status: 'OK' })> => {
|
UseInviteLink: async (request: Types.UseInviteLinkRequest): Promise<ResultError | ({ status: 'OK' })> => {
|
||||||
const auth = await params.retrieveNostrGuestWithPubAuth()
|
const auth = await params.retrieveNostrGuestWithPubAuth()
|
||||||
if (auth === null) throw new Error('retrieveNostrGuestWithPubAuth() returned null')
|
if (auth === null) throw new Error('retrieveNostrGuestWithPubAuth() returned null')
|
||||||
|
|
|
||||||
|
|
@ -363,6 +363,18 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
|
||||||
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
|
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case 'UpdateCallbackUrl':
|
||||||
|
if (!methods.UpdateCallbackUrl) {
|
||||||
|
throw new Error('method not defined: UpdateCallbackUrl')
|
||||||
|
} else {
|
||||||
|
const error = Types.CallbackUrlValidate(operation.req)
|
||||||
|
opStats.validate = process.hrtime.bigint()
|
||||||
|
if (error !== null) throw error
|
||||||
|
const res = await methods.UpdateCallbackUrl({...operation, ctx}); responses.push({ status: 'OK', ...res })
|
||||||
|
opStats.handle = process.hrtime.bigint()
|
||||||
|
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
|
||||||
|
}
|
||||||
|
break
|
||||||
case 'UserHealth':
|
case 'UserHealth':
|
||||||
if (!methods.UserHealth) {
|
if (!methods.UserHealth) {
|
||||||
throw new Error('method not defined: UserHealth')
|
throw new Error('method not defined: UserHealth')
|
||||||
|
|
@ -808,6 +820,22 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
|
||||||
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
|
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
|
||||||
}catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
|
}catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
|
||||||
break
|
break
|
||||||
|
case 'UpdateCallbackUrl':
|
||||||
|
try {
|
||||||
|
if (!methods.UpdateCallbackUrl) throw new Error('method: UpdateCallbackUrl is not implemented')
|
||||||
|
const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier)
|
||||||
|
stats.guard = process.hrtime.bigint()
|
||||||
|
authCtx = authContext
|
||||||
|
const request = req.body
|
||||||
|
const error = Types.CallbackUrlValidate(request)
|
||||||
|
stats.validate = process.hrtime.bigint()
|
||||||
|
if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback)
|
||||||
|
const response = await methods.UpdateCallbackUrl({rpcName:'UpdateCallbackUrl', ctx:authContext , req: request})
|
||||||
|
stats.handle = process.hrtime.bigint()
|
||||||
|
res({status: 'OK', ...response})
|
||||||
|
opts.metricsCallback([{ ...info, ...stats, ...authContext }])
|
||||||
|
}catch(ex){ const e = ex as any; logErrorAndReturnResponse(e, e.message || e, res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback); if (opts.throwErrors) throw e }
|
||||||
|
break
|
||||||
case 'UseInviteLink':
|
case 'UseInviteLink':
|
||||||
try {
|
try {
|
||||||
if (!methods.UseInviteLink) throw new Error('method: UseInviteLink is not implemented')
|
if (!methods.UseInviteLink) throw new Error('method: UseInviteLink is not implemented')
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ export type UserContext = {
|
||||||
app_user_id: string
|
app_user_id: string
|
||||||
user_id: string
|
user_id: string
|
||||||
}
|
}
|
||||||
export type UserMethodInputs = AddProduct_Input | AuthorizeDebit_Input | BanDebit_Input | DecodeInvoice_Input | EnrollAdminToken_Input | GetDebitAuthorizations_Input | GetLNURLChannelLink_Input | GetLnurlPayLink_Input | GetLnurlWithdrawLink_Input | GetPaymentState_Input | GetUserInfo_Input | GetUserOperations_Input | NewAddress_Input | NewInvoice_Input | NewProductInvoice_Input | OpenChannel_Input | PayAddress_Input | PayInvoice_Input | ResetDebit_Input | UserHealth_Input
|
export type UserMethodInputs = AddProduct_Input | AuthorizeDebit_Input | BanDebit_Input | DecodeInvoice_Input | EnrollAdminToken_Input | GetDebitAuthorizations_Input | GetLNURLChannelLink_Input | GetLnurlPayLink_Input | GetLnurlWithdrawLink_Input | GetPaymentState_Input | GetUserInfo_Input | GetUserOperations_Input | NewAddress_Input | NewInvoice_Input | NewProductInvoice_Input | OpenChannel_Input | PayAddress_Input | PayInvoice_Input | ResetDebit_Input | UpdateCallbackUrl_Input | UserHealth_Input
|
||||||
export type UserMethodOutputs = AddProduct_Output | AuthorizeDebit_Output | BanDebit_Output | DecodeInvoice_Output | EnrollAdminToken_Output | GetDebitAuthorizations_Output | GetLNURLChannelLink_Output | GetLnurlPayLink_Output | GetLnurlWithdrawLink_Output | GetPaymentState_Output | GetUserInfo_Output | GetUserOperations_Output | NewAddress_Output | NewInvoice_Output | NewProductInvoice_Output | OpenChannel_Output | PayAddress_Output | PayInvoice_Output | ResetDebit_Output | UserHealth_Output
|
export type UserMethodOutputs = AddProduct_Output | AuthorizeDebit_Output | BanDebit_Output | DecodeInvoice_Output | EnrollAdminToken_Output | GetDebitAuthorizations_Output | GetLNURLChannelLink_Output | GetLnurlPayLink_Output | GetLnurlWithdrawLink_Output | GetPaymentState_Output | GetUserInfo_Output | GetUserOperations_Output | NewAddress_Output | NewInvoice_Output | NewProductInvoice_Output | OpenChannel_Output | PayAddress_Output | PayInvoice_Output | ResetDebit_Output | UpdateCallbackUrl_Output | UserHealth_Output
|
||||||
export type AuthContext = AdminContext | AppContext | GuestContext | GuestWithPubContext | MetricsContext | UserContext
|
export type AuthContext = AdminContext | AppContext | GuestContext | GuestWithPubContext | MetricsContext | UserContext
|
||||||
|
|
||||||
export type AddApp_Input = {rpcName:'AddApp', req: AddAppRequest}
|
export type AddApp_Input = {rpcName:'AddApp', req: AddAppRequest}
|
||||||
|
|
@ -231,6 +231,9 @@ export type SetMockAppUserBalance_Output = ResultError | { status: 'OK' }
|
||||||
export type SetMockInvoiceAsPaid_Input = {rpcName:'SetMockInvoiceAsPaid', req: SetMockInvoiceAsPaidRequest}
|
export type SetMockInvoiceAsPaid_Input = {rpcName:'SetMockInvoiceAsPaid', req: SetMockInvoiceAsPaidRequest}
|
||||||
export type SetMockInvoiceAsPaid_Output = ResultError | { status: 'OK' }
|
export type SetMockInvoiceAsPaid_Output = ResultError | { status: 'OK' }
|
||||||
|
|
||||||
|
export type UpdateCallbackUrl_Input = {rpcName:'UpdateCallbackUrl', req: CallbackUrl}
|
||||||
|
export type UpdateCallbackUrl_Output = ResultError | ({ status: 'OK' } & CallbackUrl)
|
||||||
|
|
||||||
export type UseInviteLink_Input = {rpcName:'UseInviteLink', req: UseInviteLinkRequest}
|
export type UseInviteLink_Input = {rpcName:'UseInviteLink', req: UseInviteLinkRequest}
|
||||||
export type UseInviteLink_Output = ResultError | { status: 'OK' }
|
export type UseInviteLink_Output = ResultError | { status: 'OK' }
|
||||||
|
|
||||||
|
|
@ -294,6 +297,7 @@ export type ServerMethods = {
|
||||||
SetMockAppBalance?: (req: SetMockAppBalance_Input & {ctx: AppContext }) => Promise<void>
|
SetMockAppBalance?: (req: SetMockAppBalance_Input & {ctx: AppContext }) => Promise<void>
|
||||||
SetMockAppUserBalance?: (req: SetMockAppUserBalance_Input & {ctx: AppContext }) => Promise<void>
|
SetMockAppUserBalance?: (req: SetMockAppUserBalance_Input & {ctx: AppContext }) => Promise<void>
|
||||||
SetMockInvoiceAsPaid?: (req: SetMockInvoiceAsPaid_Input & {ctx: GuestContext }) => Promise<void>
|
SetMockInvoiceAsPaid?: (req: SetMockInvoiceAsPaid_Input & {ctx: GuestContext }) => Promise<void>
|
||||||
|
UpdateCallbackUrl?: (req: UpdateCallbackUrl_Input & {ctx: UserContext }) => Promise<CallbackUrl>
|
||||||
UseInviteLink?: (req: UseInviteLink_Input & {ctx: GuestWithPubContext }) => Promise<void>
|
UseInviteLink?: (req: UseInviteLink_Input & {ctx: GuestWithPubContext }) => Promise<void>
|
||||||
UserHealth?: (req: UserHealth_Input & {ctx: UserContext }) => Promise<void>
|
UserHealth?: (req: UserHealth_Input & {ctx: UserContext }) => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
@ -776,6 +780,24 @@ export const BannedAppUserValidate = (o?: BannedAppUser, opts: BannedAppUserOpti
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CallbackUrl = {
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
export const CallbackUrlOptionalFields: [] = []
|
||||||
|
export type CallbackUrlOptions = OptionsBaseMessage & {
|
||||||
|
checkOptionalsAreSet?: []
|
||||||
|
url_CustomCheck?: (v: string) => boolean
|
||||||
|
}
|
||||||
|
export const CallbackUrlValidate = (o?: CallbackUrl, opts: CallbackUrlOptions = {}, path: string = 'CallbackUrl::root.'): Error | null => {
|
||||||
|
if (opts.checkOptionalsAreSet && opts.allOptionalsAreSet) return new Error(path + ': only one of checkOptionalsAreSet or allOptionalNonDefault can be set for each message')
|
||||||
|
if (typeof o !== 'object' || o === null) return new Error(path + ': object is not an instance of an object or is null')
|
||||||
|
|
||||||
|
if (typeof o.url !== 'string') return new Error(`${path}.url: is not a string`)
|
||||||
|
if (opts.url_CustomCheck && !opts.url_CustomCheck(o.url)) return new Error(`${path}.url: custom check failed`)
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
export type ClosedChannel = {
|
export type ClosedChannel = {
|
||||||
capacity: number
|
capacity: number
|
||||||
channel_id: string
|
channel_id: string
|
||||||
|
|
@ -2590,6 +2612,7 @@ export const UseInviteLinkRequestValidate = (o?: UseInviteLinkRequest, opts: Use
|
||||||
|
|
||||||
export type UserInfo = {
|
export type UserInfo = {
|
||||||
balance: number
|
balance: number
|
||||||
|
callback_url: string
|
||||||
max_withdrawable: number
|
max_withdrawable: number
|
||||||
ndebit: string
|
ndebit: string
|
||||||
network_max_fee_bps: number
|
network_max_fee_bps: number
|
||||||
|
|
@ -2603,6 +2626,7 @@ export const UserInfoOptionalFields: [] = []
|
||||||
export type UserInfoOptions = OptionsBaseMessage & {
|
export type UserInfoOptions = OptionsBaseMessage & {
|
||||||
checkOptionalsAreSet?: []
|
checkOptionalsAreSet?: []
|
||||||
balance_CustomCheck?: (v: number) => boolean
|
balance_CustomCheck?: (v: number) => boolean
|
||||||
|
callback_url_CustomCheck?: (v: string) => boolean
|
||||||
max_withdrawable_CustomCheck?: (v: number) => boolean
|
max_withdrawable_CustomCheck?: (v: number) => boolean
|
||||||
ndebit_CustomCheck?: (v: string) => boolean
|
ndebit_CustomCheck?: (v: string) => boolean
|
||||||
network_max_fee_bps_CustomCheck?: (v: number) => boolean
|
network_max_fee_bps_CustomCheck?: (v: number) => boolean
|
||||||
|
|
@ -2619,6 +2643,9 @@ export const UserInfoValidate = (o?: UserInfo, opts: UserInfoOptions = {}, path:
|
||||||
if (typeof o.balance !== 'number') return new Error(`${path}.balance: is not a number`)
|
if (typeof o.balance !== 'number') return new Error(`${path}.balance: is not a number`)
|
||||||
if (opts.balance_CustomCheck && !opts.balance_CustomCheck(o.balance)) return new Error(`${path}.balance: custom check failed`)
|
if (opts.balance_CustomCheck && !opts.balance_CustomCheck(o.balance)) return new Error(`${path}.balance: custom check failed`)
|
||||||
|
|
||||||
|
if (typeof o.callback_url !== 'string') return new Error(`${path}.callback_url: is not a string`)
|
||||||
|
if (opts.callback_url_CustomCheck && !opts.callback_url_CustomCheck(o.callback_url)) return new Error(`${path}.callback_url: custom check failed`)
|
||||||
|
|
||||||
if (typeof o.max_withdrawable !== 'number') return new Error(`${path}.max_withdrawable: is not a number`)
|
if (typeof o.max_withdrawable !== 'number') return new Error(`${path}.max_withdrawable: is not a number`)
|
||||||
if (opts.max_withdrawable_CustomCheck && !opts.max_withdrawable_CustomCheck(o.max_withdrawable)) return new Error(`${path}.max_withdrawable: custom check failed`)
|
if (opts.max_withdrawable_CustomCheck && !opts.max_withdrawable_CustomCheck(o.max_withdrawable)) return new Error(`${path}.max_withdrawable: custom check failed`)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -343,6 +343,12 @@ service LightningPub {
|
||||||
option (http_route) = "/api/user/info";
|
option (http_route) = "/api/user/info";
|
||||||
option (nostr) = true;
|
option (nostr) = true;
|
||||||
}
|
}
|
||||||
|
rpc UpdateCallbackUrl(structs.CallbackUrl)returns(structs.CallbackUrl){
|
||||||
|
option (auth_type) = "User";
|
||||||
|
option (http_method) = "post";
|
||||||
|
option (http_route) = "/api/user/cb/update";
|
||||||
|
option (nostr) = true;
|
||||||
|
}
|
||||||
|
|
||||||
rpc AddProduct(structs.AddProductRequest) returns (structs.Product){
|
rpc AddProduct(structs.AddProductRequest) returns (structs.Product){
|
||||||
option (auth_type) = "User";
|
option (auth_type) = "User";
|
||||||
|
|
|
||||||
|
|
@ -347,6 +347,10 @@ message HandleLnurlPayResponse {
|
||||||
repeated Empty routes = 2;
|
repeated Empty routes = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message CallbackUrl {
|
||||||
|
string url = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message UserInfo{
|
message UserInfo{
|
||||||
string userId = 1;
|
string userId = 1;
|
||||||
int64 balance = 2;
|
int64 balance = 2;
|
||||||
|
|
@ -357,8 +361,8 @@ message UserInfo{
|
||||||
int64 network_max_fee_fixed = 7;
|
int64 network_max_fee_fixed = 7;
|
||||||
string noffer = 8;
|
string noffer = 8;
|
||||||
string ndebit = 9;
|
string ndebit = 9;
|
||||||
|
string callback_url = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetUserOperationsRequest{
|
message GetUserOperationsRequest{
|
||||||
int64 latestIncomingInvoice = 1;
|
int64 latestIncomingInvoice = 1;
|
||||||
int64 latestOutgoingInvoice = 2;
|
int64 latestOutgoingInvoice = 2;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { MainSettings } from './settings.js'
|
||||||
import ApplicationManager from './applicationManager.js'
|
import ApplicationManager from './applicationManager.js'
|
||||||
import { encodeNdebit, encodeNoffer, PriceType } from '../../custom-nip19.js'
|
import { encodeNdebit, encodeNoffer, PriceType } from '../../custom-nip19.js'
|
||||||
export default class {
|
export default class {
|
||||||
|
|
||||||
storage: Storage
|
storage: Storage
|
||||||
settings: MainSettings
|
settings: MainSettings
|
||||||
applicationManager: ApplicationManager
|
applicationManager: ApplicationManager
|
||||||
|
|
@ -51,7 +52,7 @@ export default class {
|
||||||
const app = await this.storage.applicationStorage.GetApplication(ctx.app_id)
|
const app = await this.storage.applicationStorage.GetApplication(ctx.app_id)
|
||||||
const appUser = await this.storage.applicationStorage.GetAppUserFromUser(app, user.user_id)
|
const appUser = await this.storage.applicationStorage.GetAppUserFromUser(app, user.user_id)
|
||||||
console.log("User Identifier/pointer here", appUser?.identifier)
|
console.log("User Identifier/pointer here", appUser?.identifier)
|
||||||
|
|
||||||
if (!appUser) {
|
if (!appUser) {
|
||||||
throw new Error(`app user ${ctx.user_id} not found`) // TODO: fix logs doxing
|
throw new Error(`app user ${ctx.user_id} not found`) // TODO: fix logs doxing
|
||||||
}
|
}
|
||||||
|
|
@ -64,10 +65,17 @@ export default class {
|
||||||
network_max_fee_fixed: this.settings.lndSettings.feeFixedLimit,
|
network_max_fee_fixed: this.settings.lndSettings.feeFixedLimit,
|
||||||
service_fee_bps: this.settings.outgoingAppUserInvoiceFeeBps,
|
service_fee_bps: this.settings.outgoingAppUserInvoiceFeeBps,
|
||||||
noffer: encodeNoffer({ pubkey: app.nostr_public_key!, offer: appUser.identifier, priceType: PriceType.spontaneous, relay: "" }),
|
noffer: encodeNoffer({ pubkey: app.nostr_public_key!, offer: appUser.identifier, priceType: PriceType.spontaneous, relay: "" }),
|
||||||
ndebit: encodeNdebit({ pubkey: app.nostr_public_key!, pointerId: appUser.identifier, relay: "" })
|
ndebit: encodeNdebit({ pubkey: app.nostr_public_key!, pointerId: appUser.identifier, relay: "" }),
|
||||||
|
callback_url: appUser.callback_url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async UpdateCallbackUrl(ctx: Types.UserContext, req: Types.CallbackUrl): Promise<Types.CallbackUrl> {
|
||||||
|
const app = await this.storage.applicationStorage.GetApplication(ctx.app_id)
|
||||||
|
await this.storage.applicationStorage.UpdateUserCallbackUrl(app, ctx.app_user_id, req.url)
|
||||||
|
return { url: req.url }
|
||||||
|
}
|
||||||
|
|
||||||
async NewInvoice(ctx: Types.UserContext, req: Types.NewInvoiceRequest): Promise<Types.NewInvoiceResponse> {
|
async NewInvoice(ctx: Types.UserContext, req: Types.NewInvoiceRequest): Promise<Types.NewInvoiceResponse> {
|
||||||
return this.applicationManager.AddAppUserInvoice(ctx.app_id, {
|
return this.applicationManager.AddAppUserInvoice(ctx.app_id, {
|
||||||
http_callback_url: "",
|
http_callback_url: "",
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,8 @@ export default class {
|
||||||
network_max_fee_fixed: this.settings.lndSettings.feeFixedLimit,
|
network_max_fee_fixed: this.settings.lndSettings.feeFixedLimit,
|
||||||
service_fee_bps: this.settings.outgoingAppUserInvoiceFeeBps,
|
service_fee_bps: this.settings.outgoingAppUserInvoiceFeeBps,
|
||||||
noffer: encodeNoffer({ pubkey: app.nostr_public_key!, offer: u.identifier, priceType: PriceType.spontaneous, relay: "" }),
|
noffer: encodeNoffer({ pubkey: app.nostr_public_key!, offer: u.identifier, priceType: PriceType.spontaneous, relay: "" }),
|
||||||
ndebit: encodeNdebit({ pubkey: app.nostr_public_key!, pointerId: u.identifier, relay: "" })
|
ndebit: encodeNdebit({ pubkey: app.nostr_public_key!, pointerId: u.identifier, relay: "" }),
|
||||||
|
callback_url: u.callback_url
|
||||||
|
|
||||||
},
|
},
|
||||||
max_withdrawable: this.paymentManager.GetMaxPayableInvoice(u.user.balance_sats, true)
|
max_withdrawable: this.paymentManager.GetMaxPayableInvoice(u.user.balance_sats, true)
|
||||||
|
|
@ -181,7 +182,8 @@ export default class {
|
||||||
const log = getLogger({ appName: app.name })
|
const log = getLogger({ appName: app.name })
|
||||||
const receiver = await this.storage.applicationStorage.GetApplicationUser(app, req.receiver_identifier)
|
const receiver = await this.storage.applicationStorage.GetApplicationUser(app, req.receiver_identifier)
|
||||||
const { user: payer } = await this.storage.applicationStorage.GetOrCreateApplicationUser(app, req.payer_identifier, 0)
|
const { user: payer } = await this.storage.applicationStorage.GetOrCreateApplicationUser(app, req.payer_identifier, 0)
|
||||||
const opts: InboundOptionals = { callbackUrl: req.http_callback_url, expiry: defaultInvoiceExpiry, expectedPayer: payer.user, linkedApplication: app }
|
const cbUrl = req.http_callback_url || receiver.callback_url || ""
|
||||||
|
const opts: InboundOptionals = { callbackUrl: cbUrl, expiry: defaultInvoiceExpiry, expectedPayer: payer.user, linkedApplication: app }
|
||||||
const appUserInvoice = await this.paymentManager.NewInvoice(receiver.user.user_id, req.invoice_req, opts)
|
const appUserInvoice = await this.paymentManager.NewInvoice(receiver.user.user_id, req.invoice_req, opts)
|
||||||
return {
|
return {
|
||||||
invoice: appUserInvoice.invoice
|
invoice: appUserInvoice.invoice
|
||||||
|
|
@ -201,7 +203,8 @@ export default class {
|
||||||
network_max_fee_fixed: this.settings.lndSettings.feeFixedLimit,
|
network_max_fee_fixed: this.settings.lndSettings.feeFixedLimit,
|
||||||
service_fee_bps: this.settings.outgoingAppUserInvoiceFeeBps,
|
service_fee_bps: this.settings.outgoingAppUserInvoiceFeeBps,
|
||||||
noffer: encodeNoffer({ pubkey: app.nostr_public_key!, offer: user.identifier, priceType: PriceType.spontaneous, relay: "" }),
|
noffer: encodeNoffer({ pubkey: app.nostr_public_key!, offer: user.identifier, priceType: PriceType.spontaneous, relay: "" }),
|
||||||
ndebit: encodeNdebit({ pubkey: app.nostr_public_key!, pointerId: user.identifier, relay: "" })
|
ndebit: encodeNdebit({ pubkey: app.nostr_public_key!, pointerId: user.identifier, relay: "" }),
|
||||||
|
callback_url: user.callback_url
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -228,7 +228,8 @@ export default class {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await fetch(url + "&ok=true")
|
const symbol = url.includes('?') ? "&" : "?"
|
||||||
|
await fetch(url + symbol + "ok=true")
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
log(ERROR, "error sending paid callback for invoice", err.message || "")
|
log(ERROR, "error sending paid callback for invoice", err.message || "")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,9 @@ export default (mainHandler: Main): Types.ServerMethods => {
|
||||||
},
|
},
|
||||||
UserHealth: async () => { },
|
UserHealth: async () => { },
|
||||||
GetUserInfo: ({ ctx }) => mainHandler.appUserManager.GetUserInfo(ctx),
|
GetUserInfo: ({ ctx }) => mainHandler.appUserManager.GetUserInfo(ctx),
|
||||||
|
UpdateCallbackUrl: async ({ ctx, req }) => {
|
||||||
|
return mainHandler.appUserManager.UpdateCallbackUrl(ctx, req)
|
||||||
|
},
|
||||||
GetUserOperations: async ({ ctx, req }) => {
|
GetUserOperations: async ({ ctx, req }) => {
|
||||||
return mainHandler.paymentManager.GetUserOperations(ctx.user_id, req)
|
return mainHandler.paymentManager.GetUserOperations(ctx.user_id, req)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -161,9 +161,11 @@ export default class {
|
||||||
|
|
||||||
async AddNPubToApplicationUser(serialId: number, nPub: string, entityManager = this.DB) {
|
async AddNPubToApplicationUser(serialId: number, nPub: string, entityManager = this.DB) {
|
||||||
return entityManager.getRepository(ApplicationUser).update(serialId, { nostr_public_key: nPub })
|
return entityManager.getRepository(ApplicationUser).update(serialId, { nostr_public_key: nPub })
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async UpdateUserCallbackUrl(application: Application, userIdentifier: string, callbackUrl: string, entityManager = this.DB) {
|
||||||
|
return entityManager.getRepository(ApplicationUser).update({ application: { app_id: application.app_id }, identifier: userIdentifier }, { callback_url: callbackUrl })
|
||||||
|
}
|
||||||
|
|
||||||
async RemoveApplicationUserAndBaseUser(appUser: ApplicationUser, entityManager = this.DB) {
|
async RemoveApplicationUserAndBaseUser(appUser: ApplicationUser, entityManager = this.DB) {
|
||||||
const baseUser = appUser.user;
|
const baseUser = appUser.user;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@ export class ApplicationUser {
|
||||||
@Column({ nullable: true, unique: true })
|
@Column({ nullable: true, unique: true })
|
||||||
nostr_public_key?: string
|
nostr_public_key?: string
|
||||||
|
|
||||||
|
@Column({ default: "" })
|
||||||
|
callback_url: string
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
created_at: Date
|
created_at: Date
|
||||||
|
|
||||||
|
|
|
||||||
24
src/services/storage/migrations/1727112281043-user_cb_url.ts
Normal file
24
src/services/storage/migrations/1727112281043-user_cb_url.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class UserCbUrl1727112281043 implements MigrationInterface {
|
||||||
|
name = 'UserCbUrl1727112281043'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_0a0dbb25a73306b037dec82251"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "temporary_application_user" ("serial_id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "identifier" varchar NOT NULL, "nostr_public_key" varchar, "created_at" datetime NOT NULL DEFAULT (datetime('now')), "updated_at" datetime NOT NULL DEFAULT (datetime('now')), "userSerialId" integer, "applicationSerialId" integer, "callback_url" varchar NOT NULL DEFAULT (''), CONSTRAINT "REL_0796a381bcc624f52e9a155712" UNIQUE ("userSerialId"), CONSTRAINT "UQ_3175dc397c8285d1e532554dea5" UNIQUE ("nostr_public_key"), CONSTRAINT "FK_1b3bdb6f660cd99533a1e673ef1" FOREIGN KEY ("applicationSerialId") REFERENCES "application" ("serial_id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_0796a381bcc624f52e9a155712b" FOREIGN KEY ("userSerialId") REFERENCES "user" ("serial_id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "temporary_application_user"("serial_id", "identifier", "nostr_public_key", "created_at", "updated_at", "userSerialId", "applicationSerialId") SELECT "serial_id", "identifier", "nostr_public_key", "created_at", "updated_at", "userSerialId", "applicationSerialId" FROM "application_user"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "application_user"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "temporary_application_user" RENAME TO "application_user"`);
|
||||||
|
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0a0dbb25a73306b037dec82251" ON "application_user" ("identifier") `);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_0a0dbb25a73306b037dec82251"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "application_user" RENAME TO "temporary_application_user"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "application_user" ("serial_id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "identifier" varchar NOT NULL, "nostr_public_key" varchar, "created_at" datetime NOT NULL DEFAULT (datetime('now')), "updated_at" datetime NOT NULL DEFAULT (datetime('now')), "userSerialId" integer, "applicationSerialId" integer, CONSTRAINT "REL_0796a381bcc624f52e9a155712" UNIQUE ("userSerialId"), CONSTRAINT "UQ_3175dc397c8285d1e532554dea5" UNIQUE ("nostr_public_key"), CONSTRAINT "FK_1b3bdb6f660cd99533a1e673ef1" FOREIGN KEY ("applicationSerialId") REFERENCES "application" ("serial_id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_0796a381bcc624f52e9a155712b" FOREIGN KEY ("userSerialId") REFERENCES "user" ("serial_id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "application_user"("serial_id", "identifier", "nostr_public_key", "created_at", "updated_at", "userSerialId", "applicationSerialId") SELECT "serial_id", "identifier", "nostr_public_key", "created_at", "updated_at", "userSerialId", "applicationSerialId" FROM "temporary_application_user"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "temporary_application_user"`);
|
||||||
|
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0a0dbb25a73306b037dec82251" ON "application_user" ("identifier") `);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,8 @@ import { BalanceEvents1724860966825 } from './1724860966825-balance_events.js'
|
||||||
import { DebitAccess1726496225078 } from './1726496225078-debit_access.js'
|
import { DebitAccess1726496225078 } from './1726496225078-debit_access.js'
|
||||||
import { DebitAccessFixes1726685229264 } from './1726685229264-debit_access_fixes.js'
|
import { DebitAccessFixes1726685229264 } from './1726685229264-debit_access_fixes.js'
|
||||||
import { DebitToPub1727105758354 } from './1727105758354-debit_to_pub.js'
|
import { DebitToPub1727105758354 } from './1727105758354-debit_to_pub.js'
|
||||||
const allMigrations = [Initial1703170309875, LspOrder1718387847693, LiquidityProvider1719335699480, LndNodeInfo1720187506189, TrackedProvider1720814323679, CreateInviteTokenTable1721751414878, PaymentIndex1721760297610, DebitAccess1726496225078, DebitAccessFixes1726685229264, DebitToPub1727105758354]
|
import { UserCbUrl1727112281043 } from './1727112281043-user_cb_url.js'
|
||||||
|
const allMigrations = [Initial1703170309875, LspOrder1718387847693, LiquidityProvider1719335699480, LndNodeInfo1720187506189, TrackedProvider1720814323679, CreateInviteTokenTable1721751414878, PaymentIndex1721760297610, DebitAccess1726496225078, DebitAccessFixes1726685229264, DebitToPub1727105758354, UserCbUrl1727112281043]
|
||||||
const allMetricsMigrations = [LndMetrics1703170330183, ChannelRouting1709316653538, HtlcCount1724266887195, BalanceEvents1724860966825]
|
const allMetricsMigrations = [LndMetrics1703170330183, ChannelRouting1709316653538, HtlcCount1724266887195, BalanceEvents1724860966825]
|
||||||
export const TypeOrmMigrationRunner = async (log: PubLogger, storageManager: Storage, settings: DbSettings, arg: string | undefined): Promise<boolean> => {
|
export const TypeOrmMigrationRunner = async (log: PubLogger, storageManager: Storage, settings: DbSettings, arg: string | undefined): Promise<boolean> => {
|
||||||
if (arg === 'fake_initial_migration') {
|
if (arg === 'fake_initial_migration') {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue