list swaps
This commit is contained in:
parent
bf26e2ba83
commit
5dd03063ff
17 changed files with 291 additions and 12 deletions
|
|
@ -243,6 +243,11 @@ The nostr server will send back a message response, and inside the body there wi
|
|||
- This methods has an __empty__ __request__ body
|
||||
- output: [LndChannels](#LndChannels)
|
||||
|
||||
- ListSwaps
|
||||
- auth type: __User__
|
||||
- This methods has an __empty__ __request__ body
|
||||
- output: [SwapsList](#SwapsList)
|
||||
|
||||
- LndGetInfo
|
||||
- auth type: __Admin__
|
||||
- input: [LndGetInfoRequest](#LndGetInfoRequest)
|
||||
|
|
@ -814,6 +819,13 @@ The nostr server will send back a message response, and inside the body there wi
|
|||
- This methods has an __empty__ __request__ body
|
||||
- output: [LndChannels](#LndChannels)
|
||||
|
||||
- ListSwaps
|
||||
- auth type: __User__
|
||||
- http method: __post__
|
||||
- http route: __/api/user/swap/list__
|
||||
- This methods has an __empty__ __request__ body
|
||||
- output: [SwapsList](#SwapsList)
|
||||
|
||||
- LndGetInfo
|
||||
- auth type: __Admin__
|
||||
- http method: __post__
|
||||
|
|
@ -1582,6 +1594,15 @@ The nostr server will send back a message response, and inside the body there wi
|
|||
- __page__: _number_
|
||||
- __request_id__: _number_ *this field is optional
|
||||
|
||||
### SwapOperation
|
||||
- __address_paid__: _string_
|
||||
- __failure_reason__: _string_ *this field is optional
|
||||
- __operation_payment__: _[UserOperation](#UserOperation)_ *this field is optional
|
||||
- __swap_operation_id__: _string_
|
||||
|
||||
### SwapsList
|
||||
- __swaps__: ARRAY of: _[SwapOperation](#SwapOperation)_
|
||||
|
||||
### TransactionSwapQuote
|
||||
- __chain_fee_sats__: _number_
|
||||
- __invoice_amount_sats__: _number_
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ type Client struct {
|
|||
Health func() error
|
||||
LinkNPubThroughToken func(req LinkNPubThroughTokenRequest) error
|
||||
ListChannels func() (*LndChannels, error)
|
||||
ListSwaps func() (*SwapsList, error)
|
||||
LndGetInfo func(req LndGetInfoRequest) (*LndGetInfoResponse, error)
|
||||
NewAddress func(req NewAddressRequest) (*NewAddressResponse, error)
|
||||
NewInvoice func(req NewInvoiceRequest) (*NewInvoiceResponse, error)
|
||||
|
|
@ -1632,6 +1633,32 @@ func NewClient(params ClientParams) *Client {
|
|||
}
|
||||
return &res, nil
|
||||
},
|
||||
ListSwaps: func() (*SwapsList, error) {
|
||||
auth, err := params.RetrieveUserAuth()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
finalRoute := "/api/user/swap/list"
|
||||
body := []byte{}
|
||||
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 := SwapsList{}
|
||||
err = json.Unmarshal(resBody, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
},
|
||||
LndGetInfo: func(req LndGetInfoRequest) (*LndGetInfoResponse, error) {
|
||||
auth, err := params.RetrieveAdminAuth()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -655,6 +655,15 @@ type SingleMetricReq struct {
|
|||
Page int64 `json:"page"`
|
||||
Request_id int64 `json:"request_id"`
|
||||
}
|
||||
type SwapOperation struct {
|
||||
Address_paid string `json:"address_paid"`
|
||||
Failure_reason string `json:"failure_reason"`
|
||||
Operation_payment *UserOperation `json:"operation_payment"`
|
||||
Swap_operation_id string `json:"swap_operation_id"`
|
||||
}
|
||||
type SwapsList struct {
|
||||
Swaps []SwapOperation `json:"swaps"`
|
||||
}
|
||||
type TransactionSwapQuote struct {
|
||||
Chain_fee_sats int64 `json:"chain_fee_sats"`
|
||||
Invoice_amount_sats int64 `json:"invoice_amount_sats"`
|
||||
|
|
|
|||
|
|
@ -545,6 +545,16 @@ export default (methods: Types.ServerMethods, opts: ServerOptions) => {
|
|||
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
|
||||
}
|
||||
break
|
||||
case 'ListSwaps':
|
||||
if (!methods.ListSwaps) {
|
||||
throw new Error('method ListSwaps not found' )
|
||||
} else {
|
||||
opStats.validate = opStats.guard
|
||||
const res = await methods.ListSwaps({...operation, ctx}); responses.push({ status: 'OK', ...res })
|
||||
opStats.handle = process.hrtime.bigint()
|
||||
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
|
||||
}
|
||||
break
|
||||
case 'NewAddress':
|
||||
if (!methods.NewAddress) {
|
||||
throw new Error('method NewAddress not found' )
|
||||
|
|
@ -1594,6 +1604,25 @@ 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.ListSwaps) throw new Error('method: ListSwaps is not implemented')
|
||||
app.post('/api/user/swap/list', async (req, res) => {
|
||||
const info: Types.RequestInfo = { rpcName: 'ListSwaps', 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.ListSwaps) throw new Error('method: ListSwaps 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.ListSwaps({rpcName:'ListSwaps', 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.LndGetInfo) throw new Error('method: LndGetInfo is not implemented')
|
||||
app.post('/api/admin/lnd/getinfo', async (req, res) => {
|
||||
const info: Types.RequestInfo = { rpcName: 'LndGetInfo', batch: false, nostr: false, batchSize: 0}
|
||||
|
|
|
|||
|
|
@ -781,6 +781,20 @@ export default (params: ClientParams) => ({
|
|||
}
|
||||
return { status: 'ERROR', reason: 'invalid response' }
|
||||
},
|
||||
ListSwaps: async (): Promise<ResultError | ({ status: 'OK' }& Types.SwapsList)> => {
|
||||
const auth = await params.retrieveUserAuth()
|
||||
if (auth === null) throw new Error('retrieveUserAuth() returned null')
|
||||
let finalRoute = '/api/user/swap/list'
|
||||
const { data } = await axios.post(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.SwapsListValidate(result)
|
||||
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
|
||||
}
|
||||
return { status: 'ERROR', reason: 'invalid response' }
|
||||
},
|
||||
LndGetInfo: async (request: Types.LndGetInfoRequest): Promise<ResultError | ({ status: 'OK' }& Types.LndGetInfoResponse)> => {
|
||||
const auth = await params.retrieveAdminAuth()
|
||||
if (auth === null) throw new Error('retrieveAdminAuth() returned null')
|
||||
|
|
|
|||
|
|
@ -665,6 +665,20 @@ export default (params: NostrClientParams, send: (to:string, message: NostrRequ
|
|||
}
|
||||
return { status: 'ERROR', reason: 'invalid response' }
|
||||
},
|
||||
ListSwaps: async (): Promise<ResultError | ({ status: 'OK' }& Types.SwapsList)> => {
|
||||
const auth = await params.retrieveNostrUserAuth()
|
||||
if (auth === null) throw new Error('retrieveNostrUserAuth() returned null')
|
||||
const nostrRequest: NostrRequest = {}
|
||||
const data = await send(params.pubDestination, {rpcName:'ListSwaps',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.SwapsListValidate(result)
|
||||
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
|
||||
}
|
||||
return { status: 'ERROR', reason: 'invalid response' }
|
||||
},
|
||||
LndGetInfo: async (request: Types.LndGetInfoRequest): Promise<ResultError | ({ status: 'OK' }& Types.LndGetInfoResponse)> => {
|
||||
const auth = await params.retrieveNostrAdminAuth()
|
||||
if (auth === null) throw new Error('retrieveNostrAdminAuth() returned null')
|
||||
|
|
|
|||
|
|
@ -427,6 +427,16 @@ export default (methods: Types.ServerMethods, opts: NostrOptions) => {
|
|||
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
|
||||
}
|
||||
break
|
||||
case 'ListSwaps':
|
||||
if (!methods.ListSwaps) {
|
||||
throw new Error('method not defined: ListSwaps')
|
||||
} else {
|
||||
opStats.validate = opStats.guard
|
||||
const res = await methods.ListSwaps({...operation, ctx}); responses.push({ status: 'OK', ...res })
|
||||
opStats.handle = process.hrtime.bigint()
|
||||
callsMetrics.push({ ...opInfo, ...opStats, ...ctx })
|
||||
}
|
||||
break
|
||||
case 'NewAddress':
|
||||
if (!methods.NewAddress) {
|
||||
throw new Error('method not defined: NewAddress')
|
||||
|
|
@ -1109,6 +1119,19 @@ 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 'ListSwaps':
|
||||
try {
|
||||
if (!methods.ListSwaps) throw new Error('method: ListSwaps 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.ListSwaps({rpcName:'ListSwaps', 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 'LndGetInfo':
|
||||
try {
|
||||
if (!methods.LndGetInfo) throw new Error('method: LndGetInfo is not implemented')
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ export type UserContext = {
|
|||
app_user_id: string
|
||||
user_id: string
|
||||
}
|
||||
export type UserMethodInputs = AddProduct_Input | AddUserOffer_Input | AuthorizeManage_Input | BanDebit_Input | DecodeInvoice_Input | DeleteUserOffer_Input | EditDebit_Input | EnrollAdminToken_Input | EnrollMessagingToken_Input | GetDebitAuthorizations_Input | GetHttpCreds_Input | GetLNURLChannelLink_Input | GetLnurlPayLink_Input | GetLnurlWithdrawLink_Input | GetManageAuthorizations_Input | GetPaymentState_Input | GetTransactionSwapQuote_Input | GetUserInfo_Input | GetUserOffer_Input | GetUserOfferInvoices_Input | GetUserOffers_Input | GetUserOperations_Input | NewAddress_Input | NewInvoice_Input | NewProductInvoice_Input | PayAddress_Input | PayInvoice_Input | ResetDebit_Input | ResetManage_Input | RespondToDebit_Input | UpdateCallbackUrl_Input | UpdateUserOffer_Input | UserHealth_Input
|
||||
export type UserMethodOutputs = AddProduct_Output | AddUserOffer_Output | AuthorizeManage_Output | BanDebit_Output | DecodeInvoice_Output | DeleteUserOffer_Output | EditDebit_Output | EnrollAdminToken_Output | EnrollMessagingToken_Output | GetDebitAuthorizations_Output | GetHttpCreds_Output | GetLNURLChannelLink_Output | GetLnurlPayLink_Output | GetLnurlWithdrawLink_Output | GetManageAuthorizations_Output | GetPaymentState_Output | GetTransactionSwapQuote_Output | GetUserInfo_Output | GetUserOffer_Output | GetUserOfferInvoices_Output | GetUserOffers_Output | GetUserOperations_Output | NewAddress_Output | NewInvoice_Output | NewProductInvoice_Output | PayAddress_Output | PayInvoice_Output | ResetDebit_Output | ResetManage_Output | RespondToDebit_Output | UpdateCallbackUrl_Output | UpdateUserOffer_Output | UserHealth_Output
|
||||
export type UserMethodInputs = AddProduct_Input | AddUserOffer_Input | AuthorizeManage_Input | BanDebit_Input | DecodeInvoice_Input | DeleteUserOffer_Input | EditDebit_Input | EnrollAdminToken_Input | EnrollMessagingToken_Input | GetDebitAuthorizations_Input | GetHttpCreds_Input | GetLNURLChannelLink_Input | GetLnurlPayLink_Input | GetLnurlWithdrawLink_Input | GetManageAuthorizations_Input | GetPaymentState_Input | GetTransactionSwapQuote_Input | GetUserInfo_Input | GetUserOffer_Input | GetUserOfferInvoices_Input | GetUserOffers_Input | GetUserOperations_Input | ListSwaps_Input | NewAddress_Input | NewInvoice_Input | NewProductInvoice_Input | PayAddress_Input | PayInvoice_Input | ResetDebit_Input | ResetManage_Input | RespondToDebit_Input | UpdateCallbackUrl_Input | UpdateUserOffer_Input | UserHealth_Input
|
||||
export type UserMethodOutputs = AddProduct_Output | AddUserOffer_Output | AuthorizeManage_Output | BanDebit_Output | DecodeInvoice_Output | DeleteUserOffer_Output | EditDebit_Output | EnrollAdminToken_Output | EnrollMessagingToken_Output | GetDebitAuthorizations_Output | GetHttpCreds_Output | GetLNURLChannelLink_Output | GetLnurlPayLink_Output | GetLnurlWithdrawLink_Output | GetManageAuthorizations_Output | GetPaymentState_Output | GetTransactionSwapQuote_Output | GetUserInfo_Output | GetUserOffer_Output | GetUserOfferInvoices_Output | GetUserOffers_Output | GetUserOperations_Output | ListSwaps_Output | NewAddress_Output | NewInvoice_Output | NewProductInvoice_Output | PayAddress_Output | PayInvoice_Output | ResetDebit_Output | ResetManage_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}
|
||||
|
|
@ -238,6 +238,9 @@ export type LinkNPubThroughToken_Output = ResultError | { status: 'OK' }
|
|||
export type ListChannels_Input = {rpcName:'ListChannels'}
|
||||
export type ListChannels_Output = ResultError | ({ status: 'OK' } & LndChannels)
|
||||
|
||||
export type ListSwaps_Input = {rpcName:'ListSwaps'}
|
||||
export type ListSwaps_Output = ResultError | ({ status: 'OK' } & SwapsList)
|
||||
|
||||
export type LndGetInfo_Input = {rpcName:'LndGetInfo', req: LndGetInfoRequest}
|
||||
export type LndGetInfo_Output = ResultError | ({ status: 'OK' } & LndGetInfoResponse)
|
||||
|
||||
|
|
@ -385,6 +388,7 @@ export type ServerMethods = {
|
|||
Health?: (req: Health_Input & {ctx: GuestContext }) => Promise<void>
|
||||
LinkNPubThroughToken?: (req: LinkNPubThroughToken_Input & {ctx: GuestWithPubContext }) => Promise<void>
|
||||
ListChannels?: (req: ListChannels_Input & {ctx: AdminContext }) => Promise<LndChannels>
|
||||
ListSwaps?: (req: ListSwaps_Input & {ctx: UserContext }) => Promise<SwapsList>
|
||||
LndGetInfo?: (req: LndGetInfo_Input & {ctx: AdminContext }) => Promise<LndGetInfoResponse>
|
||||
NewAddress?: (req: NewAddress_Input & {ctx: UserContext }) => Promise<NewAddressResponse>
|
||||
NewInvoice?: (req: NewInvoice_Input & {ctx: UserContext }) => Promise<NewInvoiceResponse>
|
||||
|
|
@ -3845,6 +3849,66 @@ export const SingleMetricReqValidate = (o?: SingleMetricReq, opts: SingleMetricR
|
|||
return null
|
||||
}
|
||||
|
||||
export type SwapOperation = {
|
||||
address_paid: string
|
||||
failure_reason?: string
|
||||
operation_payment?: UserOperation
|
||||
swap_operation_id: string
|
||||
}
|
||||
export type SwapOperationOptionalField = 'failure_reason' | 'operation_payment'
|
||||
export const SwapOperationOptionalFields: SwapOperationOptionalField[] = ['failure_reason', 'operation_payment']
|
||||
export type SwapOperationOptions = OptionsBaseMessage & {
|
||||
checkOptionalsAreSet?: SwapOperationOptionalField[]
|
||||
address_paid_CustomCheck?: (v: string) => boolean
|
||||
failure_reason_CustomCheck?: (v?: string) => boolean
|
||||
operation_payment_Options?: UserOperationOptions
|
||||
swap_operation_id_CustomCheck?: (v: string) => boolean
|
||||
}
|
||||
export const SwapOperationValidate = (o?: SwapOperation, opts: SwapOperationOptions = {}, path: string = 'SwapOperation::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.address_paid !== 'string') return new Error(`${path}.address_paid: is not a string`)
|
||||
if (opts.address_paid_CustomCheck && !opts.address_paid_CustomCheck(o.address_paid)) return new Error(`${path}.address_paid: custom check failed`)
|
||||
|
||||
if ((o.failure_reason || opts.allOptionalsAreSet || opts.checkOptionalsAreSet?.includes('failure_reason')) && typeof o.failure_reason !== 'string') return new Error(`${path}.failure_reason: is not a string`)
|
||||
if (opts.failure_reason_CustomCheck && !opts.failure_reason_CustomCheck(o.failure_reason)) return new Error(`${path}.failure_reason: custom check failed`)
|
||||
|
||||
if (typeof o.operation_payment === 'object' || opts.allOptionalsAreSet || opts.checkOptionalsAreSet?.includes('operation_payment')) {
|
||||
const operation_paymentErr = UserOperationValidate(o.operation_payment, opts.operation_payment_Options, `${path}.operation_payment`)
|
||||
if (operation_paymentErr !== null) return operation_paymentErr
|
||||
}
|
||||
|
||||
|
||||
if (typeof o.swap_operation_id !== 'string') return new Error(`${path}.swap_operation_id: is not a string`)
|
||||
if (opts.swap_operation_id_CustomCheck && !opts.swap_operation_id_CustomCheck(o.swap_operation_id)) return new Error(`${path}.swap_operation_id: custom check failed`)
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export type SwapsList = {
|
||||
swaps: SwapOperation[]
|
||||
}
|
||||
export const SwapsListOptionalFields: [] = []
|
||||
export type SwapsListOptions = OptionsBaseMessage & {
|
||||
checkOptionalsAreSet?: []
|
||||
swaps_ItemOptions?: SwapOperationOptions
|
||||
swaps_CustomCheck?: (v: SwapOperation[]) => boolean
|
||||
}
|
||||
export const SwapsListValidate = (o?: SwapsList, opts: SwapsListOptions = {}, path: string = 'SwapsList::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.swaps)) return new Error(`${path}.swaps: is not an array`)
|
||||
for (let index = 0; index < o.swaps.length; index++) {
|
||||
const swapsErr = SwapOperationValidate(o.swaps[index], opts.swaps_ItemOptions, `${path}.swaps[${index}]`)
|
||||
if (swapsErr !== null) return swapsErr
|
||||
}
|
||||
if (opts.swaps_CustomCheck && !opts.swaps_CustomCheck(o.swaps)) return new Error(`${path}.swaps: custom check failed`)
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export type TransactionSwapQuote = {
|
||||
chain_fee_sats: number
|
||||
invoice_amount_sats: number
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue