custom ofers

This commit is contained in:
boufni95 2024-12-04 20:27:06 +00:00
parent a945038b16
commit 1f5c3041bd
22 changed files with 1254 additions and 78 deletions

View file

@ -28,6 +28,11 @@ The nostr server will send back a message response, and inside the body there wi
- input: [AddProductRequest](#AddProductRequest)
- output: [Product](#Product)
- AddUserOffer
- auth type: __User__
- input: [OfferConfig](#OfferConfig)
- output: [OfferId](#OfferId)
- AuthApp
- auth type: __Admin__
- input: [AuthAppRequest](#AuthAppRequest)
@ -68,6 +73,11 @@ The nostr server will send back a message response, and inside the body there wi
- input: [DecodeInvoiceRequest](#DecodeInvoiceRequest)
- output: [DecodeInvoiceResponse](#DecodeInvoiceResponse)
- DeleteUserOffer
- auth type: __User__
- input: [OfferId](#OfferId)
- This methods has an __empty__ __response__ body
- EditDebit
- auth type: __User__
- input: [DebitAuthorizationRequest](#DebitAuthorizationRequest)
@ -153,6 +163,16 @@ The nostr server will send back a message response, and inside the body there wi
- This methods has an __empty__ __request__ body
- output: [UserInfo](#UserInfo)
- GetUserOffer
- auth type: __User__
- input: [OfferId](#OfferId)
- output: [OfferConfig](#OfferConfig)
- GetUserOffers
- auth type: __User__
- This methods has an __empty__ __request__ body
- output: [UserOffers](#UserOffers)
- GetUserOperations
- auth type: __User__
- input: [GetUserOperationsRequest](#GetUserOperationsRequest)
@ -225,6 +245,11 @@ The nostr server will send back a message response, and inside the body there wi
- input: [UpdateChannelPolicyRequest](#UpdateChannelPolicyRequest)
- This methods has an __empty__ __response__ body
- UpdateUserOffer
- auth type: __User__
- input: [OfferConfig](#OfferConfig)
- This methods has an __empty__ __response__ body
- UseInviteLink
- auth type: __GuestWithPub__
- input: [UseInviteLinkRequest](#UseInviteLinkRequest)
@ -311,6 +336,13 @@ The nostr server will send back a message response, and inside the body there wi
- input: [AddProductRequest](#AddProductRequest)
- output: [Product](#Product)
- AddUserOffer
- auth type: __User__
- http method: __post__
- http route: __/api/user/offer/add__
- input: [OfferConfig](#OfferConfig)
- output: [OfferId](#OfferId)
- AuthApp
- auth type: __Admin__
- http method: __post__
@ -367,6 +399,13 @@ The nostr server will send back a message response, and inside the body there wi
- input: [DecodeInvoiceRequest](#DecodeInvoiceRequest)
- output: [DecodeInvoiceResponse](#DecodeInvoiceResponse)
- DeleteUserOffer
- auth type: __User__
- http method: __post__
- http route: __/api/user/offer/delete__
- input: [OfferId](#OfferId)
- This methods has an __empty__ __response__ body
- EditDebit
- auth type: __User__
- http method: __post__
@ -539,6 +578,20 @@ The nostr server will send back a message response, and inside the body there wi
- This methods has an __empty__ __request__ body
- output: [UserInfo](#UserInfo)
- GetUserOffer
- auth type: __User__
- http method: __get__
- http route: __/api/user/offer/get__
- input: [OfferId](#OfferId)
- output: [OfferConfig](#OfferConfig)
- GetUserOffers
- auth type: __User__
- http method: __get__
- http route: __/api/user/offers/get__
- This methods has an __empty__ __request__ body
- output: [UserOffers](#UserOffers)
- GetUserOperations
- auth type: __User__
- http method: __post__
@ -733,6 +786,13 @@ The nostr server will send back a message response, and inside the body there wi
- input: [UpdateChannelPolicyRequest](#UpdateChannelPolicyRequest)
- This methods has an __empty__ __response__ body
- UpdateUserOffer
- auth type: __User__
- http method: __post__
- http route: __/api/user/offer/update__
- input: [OfferConfig](#OfferConfig)
- This methods has an __empty__ __response__ body
- UseInviteLink
- auth type: __GuestWithPub__
- http method: __post__
@ -764,6 +824,8 @@ The nostr server will send back a message response, and inside the body there wi
### AddAppUserInvoiceRequest
- __http_callback_url__: _string_
- __invoice_req__: _[NewInvoiceRequest](#NewInvoiceRequest)_
- __offer_string__: _string_ *this field is optional
- __payer_data__: _[PayerData](#PayerData)_ *this field is optional
- __payer_identifier__: _string_
- __receiver_identifier__: _string_
@ -1056,6 +1118,17 @@ The nostr server will send back a message response, and inside the body there wi
### NewInvoiceResponse
- __invoice__: _string_
### OfferConfig
- __callback_url__: _string_
- __expected_data__: MAP with key: _string_ and value: _[OfferDataType](#OfferDataType)_
- __label__: _string_
- __noffer__: _string_
- __offer_id__: _string_
- __price_sats__: _number_
### OfferId
- __offer_id__: _string_
### OpenChannel
- __active__: _boolean_
- __capacity__: _number_
@ -1106,6 +1179,9 @@ The nostr server will send back a message response, and inside the body there wi
- __preimage__: _string_
- __service_fee__: _number_
### PayerData
- __data__: MAP with key: _string_ and value: _string_
### PaymentState
- __amount__: _number_
- __network_fee__: _number_
@ -1201,6 +1277,9 @@ The nostr server will send back a message response, and inside the body there wi
- __userId__: _string_
- __user_identifier__: _string_
### UserOffers
- __offers__: ARRAY of: _[OfferConfig](#OfferConfig)_
### UserOperation
- __amount__: _number_
- __confirmed__: _boolean_
@ -1239,6 +1318,9 @@ The nostr server will send back a message response, and inside the body there wi
- __MONTH__
- __WEEK__
### OfferDataType
- __DATA_STRING__
### OperationType
- __CHAIN_OP__
- __INVOICE_OP__

View file

@ -60,6 +60,7 @@ type Client struct {
AddAppUserInvoice func(req AddAppUserInvoiceRequest) (*NewInvoiceResponse, error)
AddPeer func(req AddPeerRequest) error
AddProduct func(req AddProductRequest) (*Product, error)
AddUserOffer func(req OfferConfig) (*OfferId, error)
AuthApp func(req AuthAppRequest) (*AuthApp, error)
AuthorizeDebit func(req DebitAuthorizationRequest) (*DebitAuthorization, error)
BanDebit func(req DebitOperation) error
@ -68,6 +69,7 @@ type Client struct {
CloseChannel func(req CloseChannelRequest) (*CloseChannelResponse, error)
CreateOneTimeInviteLink func(req CreateOneTimeInviteLinkRequest) (*CreateOneTimeInviteLinkResponse, error)
DecodeInvoice func(req DecodeInvoiceRequest) (*DecodeInvoiceResponse, error)
DeleteUserOffer func(req OfferId) error
EditDebit func(req DebitAuthorizationRequest) error
EncryptionExchange func(req EncryptionExchangeRequest) error
EnrollAdminToken func(req EnrollAdminTokenRequest) error
@ -92,6 +94,8 @@ type Client struct {
GetSeed func() (*LndSeed, error)
GetUsageMetrics func() (*UsageMetrics, error)
GetUserInfo func() (*UserInfo, error)
GetUserOffer func(req OfferId) (*OfferConfig, error)
GetUserOffers func() (*UserOffers, error)
GetUserOperations func(req GetUserOperationsRequest) (*GetUserOperationsResponse, error)
HandleLnurlAddress func(routeParams HandleLnurlAddress_RouteParams) (*LnurlPayInfoResponse, error)
HandleLnurlPay func(query HandleLnurlPay_Query) (*HandleLnurlPayResponse, error)
@ -118,6 +122,7 @@ type Client struct {
SetMockInvoiceAsPaid func(req SetMockInvoiceAsPaidRequest) error
UpdateCallbackUrl func(req CallbackUrl) (*CallbackUrl, error)
UpdateChannelPolicy func(req UpdateChannelPolicyRequest) error
UpdateUserOffer func(req OfferConfig) error
UseInviteLink func(req UseInviteLinkRequest) error
UserHealth func() error
}
@ -293,6 +298,35 @@ func NewClient(params ClientParams) *Client {
}
return &res, nil
},
AddUserOffer: func(req OfferConfig) (*OfferId, error) {
auth, err := params.RetrieveUserAuth()
if err != nil {
return nil, err
}
finalRoute := "/api/user/offer/add"
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 := OfferId{}
err = json.Unmarshal(resBody, &res)
if err != nil {
return nil, err
}
return &res, nil
},
AuthApp: func(req AuthAppRequest) (*AuthApp, error) {
auth, err := params.RetrieveAdminAuth()
if err != nil {
@ -492,6 +526,30 @@ func NewClient(params ClientParams) *Client {
}
return &res, nil
},
DeleteUserOffer: func(req OfferId) error {
auth, err := params.RetrieveUserAuth()
if err != nil {
return err
}
finalRoute := "/api/user/offer/delete"
body, err := json.Marshal(req)
if err != nil {
return err
}
resBody, err := doPostRequest(params.BaseURL+finalRoute, body, auth)
if err != nil {
return err
}
result := ResultError{}
err = json.Unmarshal(resBody, &result)
if err != nil {
return err
}
if result.Status == "ERROR" {
return fmt.Errorf(result.Reason)
}
return nil
},
EditDebit: func(req DebitAuthorizationRequest) error {
auth, err := params.RetrieveUserAuth()
if err != nil {
@ -1023,6 +1081,50 @@ func NewClient(params ClientParams) *Client {
}
return &res, nil
},
GetUserOffer: func(req OfferId) (*OfferConfig, error) {
auth, err := params.RetrieveUserAuth()
if err != nil {
return nil, err
}
finalRoute := "/api/user/offer/get"
resBody, err := doGetRequest(params.BaseURL+finalRoute, auth)
result := ResultError{}
err = json.Unmarshal(resBody, &result)
if err != nil {
return nil, err
}
if result.Status == "ERROR" {
return nil, fmt.Errorf(result.Reason)
}
res := OfferConfig{}
err = json.Unmarshal(resBody, &res)
if err != nil {
return nil, err
}
return &res, nil
},
GetUserOffers: func() (*UserOffers, error) {
auth, err := params.RetrieveUserAuth()
if err != nil {
return nil, err
}
finalRoute := "/api/user/offers/get"
resBody, err := doGetRequest(params.BaseURL+finalRoute, auth)
result := ResultError{}
err = json.Unmarshal(resBody, &result)
if err != nil {
return nil, err
}
if result.Status == "ERROR" {
return nil, fmt.Errorf(result.Reason)
}
res := UserOffers{}
err = json.Unmarshal(resBody, &res)
if err != nil {
return nil, err
}
return &res, nil
},
GetUserOperations: func(req GetUserOperationsRequest) (*GetUserOperationsResponse, error) {
auth, err := params.RetrieveUserAuth()
if err != nil {
@ -1717,6 +1819,30 @@ func NewClient(params ClientParams) *Client {
}
return nil
},
UpdateUserOffer: func(req OfferConfig) error {
auth, err := params.RetrieveUserAuth()
if err != nil {
return err
}
finalRoute := "/api/user/offer/update"
body, err := json.Marshal(req)
if err != nil {
return err
}
resBody, err := doPostRequest(params.BaseURL+finalRoute, body, auth)
if err != nil {
return err
}
result := ResultError{}
err = json.Unmarshal(resBody, &result)
if err != nil {
return err
}
if result.Status == "ERROR" {
return fmt.Errorf(result.Reason)
}
return nil
},
UseInviteLink: func(req UseInviteLinkRequest) error {
auth, err := params.RetrieveGuestWithPubAuth()
if err != nil {

View file

@ -64,6 +64,12 @@ const (
WEEK IntervalType = "WEEK"
)
type OfferDataType string
const (
DATA_STRING OfferDataType = "DATA_STRING"
)
type OperationType string
const (
@ -94,6 +100,8 @@ type AddAppRequest struct {
type AddAppUserInvoiceRequest struct {
Http_callback_url string `json:"http_callback_url"`
Invoice_req *NewInvoiceRequest `json:"invoice_req"`
Offer_string string `json:"offer_string"`
Payer_data *PayerData `json:"payer_data"`
Payer_identifier string `json:"payer_identifier"`
Receiver_identifier string `json:"receiver_identifier"`
}
@ -386,6 +394,17 @@ type NewInvoiceRequest struct {
type NewInvoiceResponse struct {
Invoice string `json:"invoice"`
}
type OfferConfig struct {
Callback_url string `json:"callback_url"`
Expected_data map[string]OfferDataType `json:"expected_data"`
Label string `json:"label"`
Noffer string `json:"noffer"`
Offer_id string `json:"offer_id"`
Price_sats int64 `json:"price_sats"`
}
type OfferId struct {
Offer_id string `json:"offer_id"`
}
type OpenChannel struct {
Active bool `json:"active"`
Capacity int64 `json:"capacity"`
@ -436,6 +455,9 @@ type PayInvoiceResponse struct {
Preimage string `json:"preimage"`
Service_fee int64 `json:"service_fee"`
}
type PayerData struct {
Data map[string]string `json:"data"`
}
type PaymentState struct {
Amount int64 `json:"amount"`
Network_fee int64 `json:"network_fee"`
@ -531,6 +553,9 @@ type UserInfo struct {
Userid string `json:"userId"`
User_identifier string `json:"user_identifier"`
}
type UserOffers struct {
Offers []OfferConfig `json:"offers"`
}
type UserOperation struct {
Amount int64 `json:"amount"`
Confirmed bool `json:"confirmed"`

View file

@ -166,6 +166,28 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
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.AddUserOffer) throw new Error('method: AddUserOffer is not implemented')
app.post('/api/user/offer/add', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'AddUserOffer', 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.AddUserOffer) throw new Error('method: AddUserOffer 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.OfferConfigValidate(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.AddUserOffer({rpcName:'AddUserOffer', 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.AuthApp) throw new Error('method: AuthApp is not implemented')
app.post('/api/admin/app/auth', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'AuthApp', batch: false, nostr: false, batchSize: 0}
@ -287,6 +309,18 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'AddUserOffer':
if (!methods.AddUserOffer) {
throw new Error('method AddUserOffer not found' )
} else {
const error = Types.OfferConfigValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
const res = await methods.AddUserOffer({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'AuthorizeDebit':
if (!methods.AuthorizeDebit) {
throw new Error('method AuthorizeDebit not found' )
@ -323,6 +357,18 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'DeleteUserOffer':
if (!methods.DeleteUserOffer) {
throw new Error('method DeleteUserOffer not found' )
} else {
const error = Types.OfferIdValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
await methods.DeleteUserOffer({...operation, ctx}); responses.push({ status: 'OK' })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'EditDebit':
if (!methods.EditDebit) {
throw new Error('method EditDebit not found' )
@ -409,6 +455,28 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'GetUserOffer':
if (!methods.GetUserOffer) {
throw new Error('method GetUserOffer not found' )
} else {
const error = Types.OfferIdValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
const res = await methods.GetUserOffer({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'GetUserOffers':
if (!methods.GetUserOffers) {
throw new Error('method GetUserOffers not found' )
} else {
opStats.validate = opStats.guard
const res = await methods.GetUserOffers({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'GetUserOperations':
if (!methods.GetUserOperations) {
throw new Error('method GetUserOperations not found' )
@ -515,6 +583,18 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'UpdateUserOffer':
if (!methods.UpdateUserOffer) {
throw new Error('method UpdateUserOffer not found' )
} else {
const error = Types.OfferConfigValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
await methods.UpdateUserOffer({...operation, ctx}); responses.push({ status: 'OK' })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'UserHealth':
if (!methods.UserHealth) {
throw new Error('method UserHealth not found' )
@ -601,6 +681,28 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
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.DeleteUserOffer) throw new Error('method: DeleteUserOffer is not implemented')
app.post('/api/user/offer/delete', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'DeleteUserOffer', 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.DeleteUserOffer) throw new Error('method: DeleteUserOffer 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.OfferIdValidate(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
await methods.DeleteUserOffer({rpcName:'DeleteUserOffer', ctx:authContext , req: request})
stats.handle = process.hrtime.bigint()
res.json({status: 'OK'})
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.EditDebit) throw new Error('method: EditDebit is not implemented')
app.post('/api/user/debit/edit', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'EditDebit', batch: false, nostr: false, batchSize: 0}
@ -1011,6 +1113,47 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
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.GetUserOffer) throw new Error('method: GetUserOffer is not implemented')
app.get('/api/user/offer/get', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'GetUserOffer', 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.GetUserOffer) throw new Error('method: GetUserOffer 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.OfferIdValidate(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.GetUserOffer({rpcName:'GetUserOffer', 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.GetUserOffers) throw new Error('method: GetUserOffers is not implemented')
app.get('/api/user/offers/get', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'GetUserOffers', 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.GetUserOffers) throw new Error('method: GetUserOffers is not implemented')
const authContext = await opts.UserAuthGuard(req.headers['authorization'])
authCtx = authContext
stats.guard = process.hrtime.bigint()
stats.validate = stats.guard
const query = req.query
const params = req.params
const response = await methods.GetUserOffers({rpcName:'GetUserOffers', ctx:authContext })
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.GetUserOperations) throw new Error('method: GetUserOperations is not implemented')
app.post('/api/user/operations', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'GetUserOperations', batch: false, nostr: false, batchSize: 0}
@ -1565,6 +1708,28 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
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.UpdateUserOffer) throw new Error('method: UpdateUserOffer is not implemented')
app.post('/api/user/offer/update', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'UpdateUserOffer', 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.UpdateUserOffer) throw new Error('method: UpdateUserOffer 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.OfferConfigValidate(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
await methods.UpdateUserOffer({rpcName:'UpdateUserOffer', ctx:authContext , req: request})
stats.handle = process.hrtime.bigint()
res.json({status: 'OK'})
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')
app.post('/api/guest/invite', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'UseInviteLink', batch: false, nostr: false, batchSize: 0}

View file

@ -98,6 +98,20 @@ export default (params: ClientParams) => ({
}
return { status: 'ERROR', reason: 'invalid response' }
},
AddUserOffer: async (request: Types.OfferConfig): Promise<ResultError | ({ status: 'OK' }& Types.OfferId)> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
let finalRoute = '/api/user/offer/add'
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.OfferIdValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},
AuthApp: async (request: Types.AuthAppRequest): Promise<ResultError | ({ status: 'OK' }& Types.AuthApp)> => {
const auth = await params.retrieveAdminAuth()
if (auth === null) throw new Error('retrieveAdminAuth() returned null')
@ -204,6 +218,17 @@ export default (params: ClientParams) => ({
}
return { status: 'ERROR', reason: 'invalid response' }
},
DeleteUserOffer: async (request: Types.OfferId): Promise<ResultError | ({ status: 'OK' })> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
let finalRoute = '/api/user/offer/delete'
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') {
return data
}
return { status: 'ERROR', reason: 'invalid response' }
},
EditDebit: async (request: Types.DebitAuthorizationRequest): Promise<ResultError | ({ status: 'OK' })> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
@ -483,6 +508,34 @@ export default (params: ClientParams) => ({
}
return { status: 'ERROR', reason: 'invalid response' }
},
GetUserOffer: async (request: Types.OfferId): Promise<ResultError | ({ status: 'OK' }& Types.OfferConfig)> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
let finalRoute = '/api/user/offer/get'
const { data } = await axios.get(params.baseUrl + finalRoute, { 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.OfferConfigValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},
GetUserOffers: async (): Promise<ResultError | ({ status: 'OK' }& Types.UserOffers)> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
let finalRoute = '/api/user/offers/get'
const { data } = await axios.get(params.baseUrl + finalRoute, { 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.UserOffersValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},
GetUserOperations: async (request: Types.GetUserOperationsRequest): Promise<ResultError | ({ status: 'OK' }& Types.GetUserOperationsResponse)> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
@ -821,6 +874,17 @@ export default (params: ClientParams) => ({
}
return { status: 'ERROR', reason: 'invalid response' }
},
UpdateUserOffer: async (request: Types.OfferConfig): Promise<ResultError | ({ status: 'OK' })> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
let finalRoute = '/api/user/offer/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') {
return data
}
return { status: 'ERROR', reason: 'invalid response' }
},
UseInviteLink: async (request: Types.UseInviteLinkRequest): Promise<ResultError | ({ status: 'OK' })> => {
const auth = await params.retrieveGuestWithPubAuth()
if (auth === null) throw new Error('retrieveGuestWithPubAuth() returned null')

View file

@ -54,6 +54,21 @@ export default (params: NostrClientParams, send: (to:string, message: NostrRequ
}
return { status: 'ERROR', reason: 'invalid response' }
},
AddUserOffer: async (request: Types.OfferConfig): Promise<ResultError | ({ status: 'OK' }& Types.OfferId)> => {
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:'AddUserOffer',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.OfferIdValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},
AuthApp: async (request: Types.AuthAppRequest): Promise<ResultError | ({ status: 'OK' }& Types.AuthApp)> => {
const auth = await params.retrieveNostrAdminAuth()
if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null')
@ -167,6 +182,18 @@ export default (params: NostrClientParams, send: (to:string, message: NostrRequ
}
return { status: 'ERROR', reason: 'invalid response' }
},
DeleteUserOffer: async (request: Types.OfferId): Promise<ResultError | ({ status: 'OK' })> => {
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:'DeleteUserOffer',authIdentifier:auth, ...nostrRequest })
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
if (data.status === 'OK') {
return data
}
return { status: 'ERROR', reason: 'invalid response' }
},
EditDebit: async (request: Types.DebitAuthorizationRequest): Promise<ResultError | ({ status: 'OK' })> => {
const auth = await params.retrieveNostrUserAuth()
if (auth === null) throw new Error('retrieveNostrUserAuth() returned null')
@ -409,6 +436,34 @@ export default (params: NostrClientParams, send: (to:string, message: NostrRequ
}
return { status: 'ERROR', reason: 'invalid response' }
},
GetUserOffer: async (request: Types.OfferId): Promise<ResultError | ({ status: 'OK' }& Types.OfferConfig)> => {
const auth = await params.retrieveNostrUserAuth()
if (auth === null) throw new Error('retrieveNostrUserAuth() returned null')
const nostrRequest: NostrRequest = {}
const data = await send(params.pubDestination, {rpcName:'GetUserOffer',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.OfferConfigValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},
GetUserOffers: async (): Promise<ResultError | ({ status: 'OK' }& Types.UserOffers)> => {
const auth = await params.retrieveNostrUserAuth()
if (auth === null) throw new Error('retrieveNostrUserAuth() returned null')
const nostrRequest: NostrRequest = {}
const data = await send(params.pubDestination, {rpcName:'GetUserOffers',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.UserOffersValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},
GetUserOperations: async (request: Types.GetUserOperationsRequest): Promise<ResultError | ({ status: 'OK' }& Types.GetUserOperationsResponse)> => {
const auth = await params.retrieveNostrUserAuth()
if (auth === null) throw new Error('retrieveNostrUserAuth() returned null')
@ -606,6 +661,18 @@ export default (params: NostrClientParams, send: (to:string, message: NostrRequ
}
return { status: 'ERROR', reason: 'invalid response' }
},
UpdateUserOffer: async (request: Types.OfferConfig): Promise<ResultError | ({ status: 'OK' })> => {
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:'UpdateUserOffer',authIdentifier:auth, ...nostrRequest })
if (data.status === 'ERROR' && typeof data.reason === 'string') return data
if (data.status === 'OK') {
return data
}
return { status: 'ERROR', reason: 'invalid response' }
},
UseInviteLink: async (request: Types.UseInviteLinkRequest): Promise<ResultError | ({ status: 'OK' })> => {
const auth = await params.retrieveNostrGuestWithPubAuth()
if (auth === null) throw new Error('retrieveNostrGuestWithPubAuth() returned null')

View file

@ -80,6 +80,22 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
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 'AddUserOffer':
try {
if (!methods.AddUserOffer) throw new Error('method: AddUserOffer 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.OfferConfigValidate(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.AddUserOffer({rpcName:'AddUserOffer', 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 'AuthApp':
try {
if (!methods.AuthApp) throw new Error('method: AuthApp is not implemented')
@ -175,6 +191,18 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'AddUserOffer':
if (!methods.AddUserOffer) {
throw new Error('method not defined: AddUserOffer')
} else {
const error = Types.OfferConfigValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
const res = await methods.AddUserOffer({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'AuthorizeDebit':
if (!methods.AuthorizeDebit) {
throw new Error('method not defined: AuthorizeDebit')
@ -211,6 +239,18 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'DeleteUserOffer':
if (!methods.DeleteUserOffer) {
throw new Error('method not defined: DeleteUserOffer')
} else {
const error = Types.OfferIdValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
await methods.DeleteUserOffer({...operation, ctx}); responses.push({ status: 'OK' })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'EditDebit':
if (!methods.EditDebit) {
throw new Error('method not defined: EditDebit')
@ -297,6 +337,28 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'GetUserOffer':
if (!methods.GetUserOffer) {
throw new Error('method not defined: GetUserOffer')
} else {
const error = Types.OfferIdValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
const res = await methods.GetUserOffer({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'GetUserOffers':
if (!methods.GetUserOffers) {
throw new Error('method not defined: GetUserOffers')
} else {
opStats.validate = opStats.guard
const res = await methods.GetUserOffers({...operation, ctx}); responses.push({ status: 'OK', ...res })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'GetUserOperations':
if (!methods.GetUserOperations) {
throw new Error('method not defined: GetUserOperations')
@ -403,6 +465,18 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'UpdateUserOffer':
if (!methods.UpdateUserOffer) {
throw new Error('method not defined: UpdateUserOffer')
} else {
const error = Types.OfferConfigValidate(operation.req)
opStats.validate = process.hrtime.bigint()
if (error !== null) throw error
await methods.UpdateUserOffer({...operation, ctx}); responses.push({ status: 'OK' })
opStats.handle = process.hrtime.bigint()
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
}
break
case 'UserHealth':
if (!methods.UserHealth) {
throw new Error('method not defined: UserHealth')
@ -471,6 +545,22 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
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 'DeleteUserOffer':
try {
if (!methods.DeleteUserOffer) throw new Error('method: DeleteUserOffer 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.OfferIdValidate(request)
stats.validate = process.hrtime.bigint()
if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback)
await methods.DeleteUserOffer({rpcName:'DeleteUserOffer', ctx:authContext , req: request})
stats.handle = process.hrtime.bigint()
res({status: 'OK'})
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 'EditDebit':
try {
if (!methods.EditDebit) throw new Error('method: EditDebit is not implemented')
@ -710,6 +800,35 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
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 'GetUserOffer':
try {
if (!methods.GetUserOffer) throw new Error('method: GetUserOffer 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.OfferIdValidate(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.GetUserOffer({rpcName:'GetUserOffer', 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 'GetUserOffers':
try {
if (!methods.GetUserOffers) throw new Error('method: GetUserOffers is not implemented')
const authContext = await opts.NostrUserAuthGuard(req.appId, req.authIdentifier)
stats.guard = process.hrtime.bigint()
authCtx = authContext
stats.validate = stats.guard
const response = await methods.GetUserOffers({rpcName:'GetUserOffers', ctx:authContext })
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 'GetUserOperations':
try {
if (!methods.GetUserOperations) throw new Error('method: GetUserOperations is not implemented')
@ -928,6 +1047,22 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
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 'UpdateUserOffer':
try {
if (!methods.UpdateUserOffer) throw new Error('method: UpdateUserOffer 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.OfferConfigValidate(request)
stats.validate = process.hrtime.bigint()
if (error !== null) return logErrorAndReturnResponse(error, 'invalid request body', res, logger, { ...info, ...stats, ...authCtx }, opts.metricsCallback)
await methods.UpdateUserOffer({rpcName:'UpdateUserOffer', ctx:authContext , req: request})
stats.handle = process.hrtime.bigint()
res({status: 'OK'})
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':
try {
if (!methods.UseInviteLink) throw new Error('method: UseInviteLink is not implemented')

View file

@ -34,8 +34,8 @@ export type UserContext = {
app_user_id: string
user_id: string
}
export type UserMethodInputs = AddProduct_Input | AuthorizeDebit_Input | BanDebit_Input | DecodeInvoice_Input | EditDebit_Input | EnrollAdminToken_Input | GetDebitAuthorizations_Input | GetLNURLChannelLink_Input | GetLnurlPayLink_Input | GetLnurlWithdrawLink_Input | GetPaymentState_Input | GetUserInfo_Input | GetUserOperations_Input | NewAddress_Input | NewInvoice_Input | NewProductInvoice_Input | PayAddress_Input | PayInvoice_Input | ResetDebit_Input | RespondToDebit_Input | UpdateCallbackUrl_Input | UserHealth_Input
export type UserMethodOutputs = AddProduct_Output | AuthorizeDebit_Output | BanDebit_Output | DecodeInvoice_Output | EditDebit_Output | EnrollAdminToken_Output | GetDebitAuthorizations_Output | GetLNURLChannelLink_Output | GetLnurlPayLink_Output | GetLnurlWithdrawLink_Output | GetPaymentState_Output | GetUserInfo_Output | GetUserOperations_Output | NewAddress_Output | NewInvoice_Output | NewProductInvoice_Output | PayAddress_Output | PayInvoice_Output | ResetDebit_Output | RespondToDebit_Output | UpdateCallbackUrl_Output | UserHealth_Output
export type UserMethodInputs = AddProduct_Input | AddUserOffer_Input | AuthorizeDebit_Input | BanDebit_Input | DecodeInvoice_Input | DeleteUserOffer_Input | EditDebit_Input | EnrollAdminToken_Input | GetDebitAuthorizations_Input | GetLNURLChannelLink_Input | GetLnurlPayLink_Input | GetLnurlWithdrawLink_Input | GetPaymentState_Input | GetUserInfo_Input | GetUserOffer_Input | GetUserOffers_Input | GetUserOperations_Input | NewAddress_Input | NewInvoice_Input | NewProductInvoice_Input | PayAddress_Input | PayInvoice_Input | ResetDebit_Input | RespondToDebit_Input | UpdateCallbackUrl_Input | UpdateUserOffer_Input | UserHealth_Input
export type UserMethodOutputs = AddProduct_Output | AddUserOffer_Output | AuthorizeDebit_Output | BanDebit_Output | DecodeInvoice_Output | DeleteUserOffer_Output | EditDebit_Output | EnrollAdminToken_Output | GetDebitAuthorizations_Output | GetLNURLChannelLink_Output | GetLnurlPayLink_Output | GetLnurlWithdrawLink_Output | GetPaymentState_Output | GetUserInfo_Output | GetUserOffer_Output | GetUserOffers_Output | GetUserOperations_Output | NewAddress_Output | NewInvoice_Output | NewProductInvoice_Output | PayAddress_Output | PayInvoice_Output | ResetDebit_Output | RespondToDebit_Output | UpdateCallbackUrl_Output | UpdateUserOffer_Output | UserHealth_Output
export type AuthContext = AdminContext | AppContext | GuestContext | GuestWithPubContext | MetricsContext | UserContext
export type AddApp_Input = {rpcName:'AddApp', req: AddAppRequest}
@ -56,6 +56,9 @@ export type AddPeer_Output = ResultError | { status: 'OK' }
export type AddProduct_Input = {rpcName:'AddProduct', req: AddProductRequest}
export type AddProduct_Output = ResultError | ({ status: 'OK' } & Product)
export type AddUserOffer_Input = {rpcName:'AddUserOffer', req: OfferConfig}
export type AddUserOffer_Output = ResultError | ({ status: 'OK' } & OfferId)
export type AuthApp_Input = {rpcName:'AuthApp', req: AuthAppRequest}
export type AuthApp_Output = ResultError | ({ status: 'OK' } & AuthApp)
@ -80,6 +83,9 @@ export type CreateOneTimeInviteLink_Output = ResultError | ({ status: 'OK' } & C
export type DecodeInvoice_Input = {rpcName:'DecodeInvoice', req: DecodeInvoiceRequest}
export type DecodeInvoice_Output = ResultError | ({ status: 'OK' } & DecodeInvoiceResponse)
export type DeleteUserOffer_Input = {rpcName:'DeleteUserOffer', req: OfferId}
export type DeleteUserOffer_Output = ResultError | { status: 'OK' }
export type EditDebit_Input = {rpcName:'EditDebit', req: DebitAuthorizationRequest}
export type EditDebit_Output = ResultError | { status: 'OK' }
@ -158,6 +164,12 @@ export type GetUsageMetrics_Output = ResultError | ({ status: 'OK' } & UsageMetr
export type GetUserInfo_Input = {rpcName:'GetUserInfo'}
export type GetUserInfo_Output = ResultError | ({ status: 'OK' } & UserInfo)
export type GetUserOffer_Input = {rpcName:'GetUserOffer', req: OfferId}
export type GetUserOffer_Output = ResultError | ({ status: 'OK' } & OfferConfig)
export type GetUserOffers_Input = {rpcName:'GetUserOffers'}
export type GetUserOffers_Output = ResultError | ({ status: 'OK' } & UserOffers)
export type GetUserOperations_Input = {rpcName:'GetUserOperations', req: GetUserOperationsRequest}
export type GetUserOperations_Output = ResultError | ({ status: 'OK' } & GetUserOperationsResponse)
@ -252,6 +264,9 @@ export type UpdateCallbackUrl_Output = ResultError | ({ status: 'OK' } & Callbac
export type UpdateChannelPolicy_Input = {rpcName:'UpdateChannelPolicy', req: UpdateChannelPolicyRequest}
export type UpdateChannelPolicy_Output = ResultError | { status: 'OK' }
export type UpdateUserOffer_Input = {rpcName:'UpdateUserOffer', req: OfferConfig}
export type UpdateUserOffer_Output = ResultError | { status: 'OK' }
export type UseInviteLink_Input = {rpcName:'UseInviteLink', req: UseInviteLinkRequest}
export type UseInviteLink_Output = ResultError | { status: 'OK' }
@ -265,6 +280,7 @@ export type ServerMethods = {
AddAppUserInvoice?: (req: AddAppUserInvoice_Input & {ctx: AppContext }) => Promise<NewInvoiceResponse>
AddPeer?: (req: AddPeer_Input & {ctx: AdminContext }) => Promise<void>
AddProduct?: (req: AddProduct_Input & {ctx: UserContext }) => Promise<Product>
AddUserOffer?: (req: AddUserOffer_Input & {ctx: UserContext }) => Promise<OfferId>
AuthApp?: (req: AuthApp_Input & {ctx: AdminContext }) => Promise<AuthApp>
AuthorizeDebit?: (req: AuthorizeDebit_Input & {ctx: UserContext }) => Promise<DebitAuthorization>
BanDebit?: (req: BanDebit_Input & {ctx: UserContext }) => Promise<void>
@ -272,6 +288,7 @@ export type ServerMethods = {
CloseChannel?: (req: CloseChannel_Input & {ctx: AdminContext }) => Promise<CloseChannelResponse>
CreateOneTimeInviteLink?: (req: CreateOneTimeInviteLink_Input & {ctx: AdminContext }) => Promise<CreateOneTimeInviteLinkResponse>
DecodeInvoice?: (req: DecodeInvoice_Input & {ctx: UserContext }) => Promise<DecodeInvoiceResponse>
DeleteUserOffer?: (req: DeleteUserOffer_Input & {ctx: UserContext }) => Promise<void>
EditDebit?: (req: EditDebit_Input & {ctx: UserContext }) => Promise<void>
EncryptionExchange?: (req: EncryptionExchange_Input & {ctx: GuestContext }) => Promise<void>
EnrollAdminToken?: (req: EnrollAdminToken_Input & {ctx: UserContext }) => Promise<void>
@ -296,6 +313,8 @@ export type ServerMethods = {
GetSeed?: (req: GetSeed_Input & {ctx: AdminContext }) => Promise<LndSeed>
GetUsageMetrics?: (req: GetUsageMetrics_Input & {ctx: MetricsContext }) => Promise<UsageMetrics>
GetUserInfo?: (req: GetUserInfo_Input & {ctx: UserContext }) => Promise<UserInfo>
GetUserOffer?: (req: GetUserOffer_Input & {ctx: UserContext }) => Promise<OfferConfig>
GetUserOffers?: (req: GetUserOffers_Input & {ctx: UserContext }) => Promise<UserOffers>
GetUserOperations?: (req: GetUserOperations_Input & {ctx: UserContext }) => Promise<GetUserOperationsResponse>
HandleLnurlAddress?: (req: HandleLnurlAddress_Input & {ctx: GuestContext }) => Promise<LnurlPayInfoResponse>
HandleLnurlPay?: (req: HandleLnurlPay_Input & {ctx: GuestContext }) => Promise<HandleLnurlPayResponse>
@ -322,6 +341,7 @@ export type ServerMethods = {
SetMockInvoiceAsPaid?: (req: SetMockInvoiceAsPaid_Input & {ctx: GuestContext }) => Promise<void>
UpdateCallbackUrl?: (req: UpdateCallbackUrl_Input & {ctx: UserContext }) => Promise<CallbackUrl>
UpdateChannelPolicy?: (req: UpdateChannelPolicy_Input & {ctx: AdminContext }) => Promise<void>
UpdateUserOffer?: (req: UpdateUserOffer_Input & {ctx: UserContext }) => Promise<void>
UseInviteLink?: (req: UseInviteLink_Input & {ctx: GuestWithPubContext }) => Promise<void>
UserHealth?: (req: UserHealth_Input & {ctx: UserContext }) => Promise<void>
}
@ -344,6 +364,13 @@ export const enumCheckIntervalType = (e?: IntervalType): boolean => {
for (const v in IntervalType) if (e === v) return true
return false
}
export enum OfferDataType {
DATA_STRING = 'DATA_STRING',
}
export const enumCheckOfferDataType = (e?: OfferDataType): boolean => {
for (const v in OfferDataType) if (e === v) return true
return false
}
export enum OperationType {
CHAIN_OP = 'CHAIN_OP',
INVOICE_OP = 'INVOICE_OP',
@ -424,14 +451,19 @@ export const AddAppRequestValidate = (o?: AddAppRequest, opts: AddAppRequestOpti
export type AddAppUserInvoiceRequest = {
http_callback_url: string
invoice_req: NewInvoiceRequest
offer_string?: string
payer_data?: PayerData
payer_identifier: string
receiver_identifier: string
}
export const AddAppUserInvoiceRequestOptionalFields: [] = []
export type AddAppUserInvoiceRequestOptionalField = 'offer_string' | 'payer_data'
export const AddAppUserInvoiceRequestOptionalFields: AddAppUserInvoiceRequestOptionalField[] = ['offer_string', 'payer_data']
export type AddAppUserInvoiceRequestOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: []
checkOptionalsAreSet?: AddAppUserInvoiceRequestOptionalField[]
http_callback_url_CustomCheck?: (v: string) => boolean
invoice_req_Options?: NewInvoiceRequestOptions
offer_string_CustomCheck?: (v?: string) => boolean
payer_data_Options?: PayerDataOptions
payer_identifier_CustomCheck?: (v: string) => boolean
receiver_identifier_CustomCheck?: (v: string) => boolean
}
@ -446,6 +478,15 @@ export const AddAppUserInvoiceRequestValidate = (o?: AddAppUserInvoiceRequest, o
if (invoice_reqErr !== null) return invoice_reqErr
if ((o.offer_string || opts.allOptionalsAreSet || opts.checkOptionalsAreSet?.includes('offer_string')) && typeof o.offer_string !== 'string') return new Error(`${path}.offer_string: is not a string`)
if (opts.offer_string_CustomCheck && !opts.offer_string_CustomCheck(o.offer_string)) return new Error(`${path}.offer_string: custom check failed`)
if (typeof o.payer_data === 'object' || opts.allOptionalsAreSet || opts.checkOptionalsAreSet?.includes('payer_data')) {
const payer_dataErr = PayerDataValidate(o.payer_data, opts.payer_data_Options, `${path}.payer_data`)
if (payer_dataErr !== null) return payer_dataErr
}
if (typeof o.payer_identifier !== 'string') return new Error(`${path}.payer_identifier: is not a string`)
if (opts.payer_identifier_CustomCheck && !opts.payer_identifier_CustomCheck(o.payer_identifier)) return new Error(`${path}.payer_identifier: custom check failed`)
@ -2201,6 +2242,69 @@ export const NewInvoiceResponseValidate = (o?: NewInvoiceResponse, opts: NewInvo
return null
}
export type OfferConfig = {
callback_url: string
expected_data: Record<string, OfferDataType>
label: string
noffer: string
offer_id: string
price_sats: number
}
export const OfferConfigOptionalFields: [] = []
export type OfferConfigOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: []
callback_url_CustomCheck?: (v: string) => boolean
expected_data_CustomCheck?: (v: Record<string, OfferDataType>) => boolean
label_CustomCheck?: (v: string) => boolean
noffer_CustomCheck?: (v: string) => boolean
offer_id_CustomCheck?: (v: string) => boolean
price_sats_CustomCheck?: (v: number) => boolean
}
export const OfferConfigValidate = (o?: OfferConfig, opts: OfferConfigOptions = {}, path: string = 'OfferConfig::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.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.expected_data !== 'object' || o.expected_data === null) return new Error(`${path}.expected_data: is not an object or is null`)
for (const key in o.expected_data) {
if (!enumCheckOfferDataType(o.expected_data[key])) return new Error(`${path}.expected_data['${key}']: is not a OfferDataType`)
}
if (typeof o.label !== 'string') return new Error(`${path}.label: is not a string`)
if (opts.label_CustomCheck && !opts.label_CustomCheck(o.label)) return new Error(`${path}.label: custom check failed`)
if (typeof o.noffer !== 'string') return new Error(`${path}.noffer: is not a string`)
if (opts.noffer_CustomCheck && !opts.noffer_CustomCheck(o.noffer)) return new Error(`${path}.noffer: custom check failed`)
if (typeof o.offer_id !== 'string') return new Error(`${path}.offer_id: is not a string`)
if (opts.offer_id_CustomCheck && !opts.offer_id_CustomCheck(o.offer_id)) return new Error(`${path}.offer_id: custom check failed`)
if (typeof o.price_sats !== 'number') return new Error(`${path}.price_sats: is not a number`)
if (opts.price_sats_CustomCheck && !opts.price_sats_CustomCheck(o.price_sats)) return new Error(`${path}.price_sats: custom check failed`)
return null
}
export type OfferId = {
offer_id: string
}
export const OfferIdOptionalFields: [] = []
export type OfferIdOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: []
offer_id_CustomCheck?: (v: string) => boolean
}
export const OfferIdValidate = (o?: OfferId, opts: OfferIdOptions = {}, path: string = 'OfferId::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.offer_id !== 'string') return new Error(`${path}.offer_id: is not a string`)
if (opts.offer_id_CustomCheck && !opts.offer_id_CustomCheck(o.offer_id)) return new Error(`${path}.offer_id: custom check failed`)
return null
}
export type OpenChannel = {
active: boolean
capacity: number
@ -2482,6 +2586,26 @@ export const PayInvoiceResponseValidate = (o?: PayInvoiceResponse, opts: PayInvo
return null
}
export type PayerData = {
data: Record<string, string>
}
export const PayerDataOptionalFields: [] = []
export type PayerDataOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: []
data_CustomCheck?: (v: Record<string, string>) => boolean
}
export const PayerDataValidate = (o?: PayerData, opts: PayerDataOptions = {}, path: string = 'PayerData::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.data !== 'object' || o.data === null) return new Error(`${path}.data: is not an object or is null`)
for (const key in o.data) {
if (typeof o.data[key] !== 'string') return new Error(`${path}.data['${key}']: is not a string`)
}
return null
}
export type PaymentState = {
amount: number
network_fee: number
@ -3018,6 +3142,29 @@ export const UserInfoValidate = (o?: UserInfo, opts: UserInfoOptions = {}, path:
return null
}
export type UserOffers = {
offers: OfferConfig[]
}
export const UserOffersOptionalFields: [] = []
export type UserOffersOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: []
offers_ItemOptions?: OfferConfigOptions
offers_CustomCheck?: (v: OfferConfig[]) => boolean
}
export const UserOffersValidate = (o?: UserOffers, opts: UserOffersOptions = {}, path: string = 'UserOffers::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 (!Array.isArray(o.offers)) return new Error(`${path}.offers: is not an array`)
for (let index = 0; index < o.offers.length; index++) {
const offersErr = OfferConfigValidate(o.offers[index], opts.offers_ItemOptions, `${path}.offers[${index}]`)
if (offersErr !== null) return offersErr
}
if (opts.offers_CustomCheck && !opts.offers_CustomCheck(o.offers)) return new Error(`${path}.offers: custom check failed`)
return null
}
export type UserOperation = {
amount: number
confirmed: boolean

View file

@ -467,6 +467,42 @@ service LightningPub {
option (http_route) = "/api/user/lnurl_channel/url";
option (nostr) = true;
}
rpc GetUserOffers(structs.Empty) returns (structs.UserOffers){
option (auth_type) = "User";
option (http_method) = "get";
option (http_route) = "/api/user/offers/get";
option (nostr) = true;
}
rpc GetUserOffer(structs.OfferId) returns (structs.OfferConfig){
option (auth_type) = "User";
option (http_method) = "get";
option (http_route) = "/api/user/offer/get";
option (nostr) = true;
}
rpc UpdateUserOffer(structs.OfferConfig) returns (structs.Empty){
option (auth_type) = "User";
option (http_method) = "post";
option (http_route) = "/api/user/offer/update";
option (nostr) = true;
}
rpc DeleteUserOffer(structs.OfferId) returns (structs.Empty){
option (auth_type) = "User";
option (http_method) = "post";
option (http_route) = "/api/user/offer/delete";
option (nostr) = true;
}
rpc AddUserOffer(structs.OfferConfig) returns (structs.OfferId){
option (auth_type) = "User";
option (http_method) = "post";
option (http_route) = "/api/user/offer/add";
option (nostr) = true;
}
rpc GetDebitAuthorizations(structs.Empty) returns (structs.DebitAuthorizations){
option (auth_type) = "User";
option (http_method) = "get";

View file

@ -269,6 +269,8 @@ message AddAppUserInvoiceRequest {
string payer_identifier = 2;
string http_callback_url = 3;
NewInvoiceRequest invoice_req = 4;
optional PayerData payer_data = 5;
optional string offer_string = 6;
}
message GetAppUserRequest {
@ -331,6 +333,10 @@ message PayAddressResponse{
int64 network_fee = 4;
}
message PayerData {
map<string,string> data = 1;
}
message NewInvoiceRequest{
int64 amountSats = 1;
string memo = 2;
@ -613,4 +619,25 @@ message DebitResponse {
Empty denied = 3;
string invoice = 4;
}
}
enum OfferDataType {
DATA_STRING = 0;
}
message OfferId {
string offer_id = 1;
}
message OfferConfig {
string offer_id = 1;
string label = 2;
int64 price_sats = 3;
string callback_url = 4;
map<string, OfferDataType> expected_data = 5;
string noffer = 6;
}
message UserOffers {
repeated OfferConfig offers = 1;
}