Skip to content

Commit

Permalink
fix linking
Browse files Browse the repository at this point in the history
  • Loading branch information
boufni95 committed Oct 16, 2024
1 parent fb17b05 commit 24e0c67
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 4 deletions.
13 changes: 13 additions & 0 deletions proto/autogenerated/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,13 @@ The nostr server will send back a message response, and inside the body there wi
- This methods has an __empty__ __request__ body
- output: [MigrationUpdate](#MigrationUpdate)

- GetNPubLinkingState
- auth type: __App__
- http method: __post__
- http route: __/api/app/user/npub/token__
- input: [GetNPubLinking](#GetNPubLinking)
- output: [NPubLinking](#NPubLinking)

- GetPaymentState
- auth type: __User__
- http method: __post__
Expand Down Expand Up @@ -862,6 +869,9 @@ The nostr server will send back a message response, and inside the body there wi
### GetInviteTokenStateResponse
- __used__: _boolean_

### GetNPubLinking
- __user_identifier__: _string_

### GetPaymentStateRequest
- __invoice__: _string_

Expand Down Expand Up @@ -967,6 +977,9 @@ The nostr server will send back a message response, and inside the body there wi
- __closure__: _[ClosureMigration](#ClosureMigration)_ *this field is optional
- __relays__: _[RelaysMigration](#RelaysMigration)_ *this field is optional

### NPubLinking
- __state__: _[NPubLinking_state](#NPubLinking_state)_

### NewAddressRequest
- __addressType__: _[AddressType](#AddressType)_

Expand Down
30 changes: 30 additions & 0 deletions proto/autogenerated/go/http_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type Client struct {
GetLnurlWithdrawInfo func(query GetLnurlWithdrawInfo_Query) (*LnurlWithdrawInfoResponse, error)
GetLnurlWithdrawLink func() (*LnurlLinkResponse, error)
GetMigrationUpdate func() (*MigrationUpdate, error)
GetNPubLinkingState func(req GetNPubLinking) (*NPubLinking, error)
GetPaymentState func(req GetPaymentStateRequest) (*PaymentState, error)
GetSeed func() (*LndSeed, error)
GetUsageMetrics func() (*UsageMetrics, error)
Expand Down Expand Up @@ -834,6 +835,35 @@ func NewClient(params ClientParams) *Client {
return &res, nil
},
// server streaming method: GetMigrationUpdate not implemented
GetNPubLinkingState: func(req GetNPubLinking) (*NPubLinking, error) {
auth, err := params.RetrieveAppAuth()
if err != nil {
return nil, err
}
finalRoute := "/api/app/user/npub/token"
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 := NPubLinking{}
err = json.Unmarshal(resBody, &res)
if err != nil {
return nil, err
}
return &res, nil
},
GetPaymentState: func(req GetPaymentStateRequest) (*PaymentState, error) {
auth, err := params.RetrieveUserAuth()
if err != nil {
Expand Down
20 changes: 20 additions & 0 deletions proto/autogenerated/go/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ type GetInviteTokenStateRequest struct {
type GetInviteTokenStateResponse struct {
Used bool `json:"used"`
}
type GetNPubLinking struct {
User_identifier string `json:"user_identifier"`
}
type GetPaymentStateRequest struct {
Invoice string `json:"invoice"`
}
Expand Down Expand Up @@ -333,6 +336,9 @@ type MigrationUpdate struct {
Closure *ClosureMigration `json:"closure"`
Relays *RelaysMigration `json:"relays"`
}
type NPubLinking struct {
State *NPubLinking_state `json:"state"`
}
type NewAddressRequest struct {
Addresstype AddressType `json:"addressType"`
}
Expand Down Expand Up @@ -542,3 +548,17 @@ type LiveDebitRequest_debit struct {
Full_access *Empty `json:"full_access"`
Invoice *string `json:"invoice"`
}
type NPubLinking_state_type string

const (
LINKED_NPUB NPubLinking_state_type = "linked_npub"
LINKING_TOKEN NPubLinking_state_type = "linking_token"
UNLINKED NPubLinking_state_type = "unlinked"
)

type NPubLinking_state struct {
Type NPubLinking_state_type `json:"type"`
Linked_npub *string `json:"linked_npub"`
Linking_token *string `json:"linking_token"`
Unlinked *Empty `json:"unlinked"`
}
22 changes: 22 additions & 0 deletions proto/autogenerated/ts/express_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,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.GetNPubLinkingState) throw new Error('method: GetNPubLinkingState is not implemented')
app.post('/api/app/user/npub/token', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'GetNPubLinkingState', 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.GetNPubLinkingState) throw new Error('method: GetNPubLinkingState is not implemented')
const authContext = await opts.AppAuthGuard(req.headers['authorization'])
authCtx = authContext
stats.guard = process.hrtime.bigint()
const request = req.body
const error = Types.GetNPubLinkingValidate(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.GetNPubLinkingState({rpcName:'GetNPubLinkingState', 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.GetPaymentState) throw new Error('method: GetPaymentState is not implemented')
app.post('/api/user/payment/state', async (req, res) => {
const info: Types.RequestInfo = { rpcName: 'GetPaymentState', batch: false, nostr: false, batchSize: 0}
Expand Down
14 changes: 14 additions & 0 deletions proto/autogenerated/ts/http_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,20 @@ export default (params: ClientParams) => ({
return { status: 'ERROR', reason: 'invalid response' }
},
GetMigrationUpdate: async (cb: (v:ResultError | ({ status: 'OK' }& Types.MigrationUpdate)) => void): Promise<void> => { throw new Error('http streams are not supported')},
GetNPubLinkingState: async (request: Types.GetNPubLinking): Promise<ResultError | ({ status: 'OK' }& Types.NPubLinking)> => {
const auth = await params.retrieveAppAuth()
if (auth === null) throw new Error('retrieveAppAuth() returned null')
let finalRoute = '/api/app/user/npub/token'
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.NPubLinkingValidate(result)
if (error === null) { return { status: 'OK', ...result } } else return { status: 'ERROR', reason: error.message }
}
return { status: 'ERROR', reason: 'invalid response' }
},
GetPaymentState: async (request: Types.GetPaymentStateRequest): Promise<ResultError | ({ status: 'OK' }& Types.PaymentState)> => {
const auth = await params.retrieveUserAuth()
if (auth === null) throw new Error('retrieveUserAuth() returned null')
Expand Down
89 changes: 87 additions & 2 deletions proto/autogenerated/ts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export type AdminMethodOutputs = AddApp_Output | AuthApp_Output | BanUser_Output
export type AppContext = {
app_id: string
}
export type AppMethodInputs = AddAppInvoice_Input | AddAppUser_Input | AddAppUserInvoice_Input | GetApp_Input | GetAppUser_Input | GetAppUserLNURLInfo_Input | PayAppUserInvoice_Input | RequestNPubLinkingToken_Input | ResetNPubLinkingToken_Input | SendAppUserToAppPayment_Input | SendAppUserToAppUserPayment_Input | SetMockAppBalance_Input | SetMockAppUserBalance_Input
export type AppMethodOutputs = AddAppInvoice_Output | AddAppUser_Output | AddAppUserInvoice_Output | GetApp_Output | GetAppUser_Output | GetAppUserLNURLInfo_Output | PayAppUserInvoice_Output | RequestNPubLinkingToken_Output | ResetNPubLinkingToken_Output | SendAppUserToAppPayment_Output | SendAppUserToAppUserPayment_Output | SetMockAppBalance_Output | SetMockAppUserBalance_Output
export type AppMethodInputs = AddAppInvoice_Input | AddAppUser_Input | AddAppUserInvoice_Input | GetApp_Input | GetAppUser_Input | GetAppUserLNURLInfo_Input | GetNPubLinkingState_Input | PayAppUserInvoice_Input | RequestNPubLinkingToken_Input | ResetNPubLinkingToken_Input | SendAppUserToAppPayment_Input | SendAppUserToAppUserPayment_Input | SetMockAppBalance_Input | SetMockAppUserBalance_Input
export type AppMethodOutputs = AddAppInvoice_Output | AddAppUser_Output | AddAppUserInvoice_Output | GetApp_Output | GetAppUser_Output | GetAppUserLNURLInfo_Output | GetNPubLinkingState_Output | PayAppUserInvoice_Output | RequestNPubLinkingToken_Output | ResetNPubLinkingToken_Output | SendAppUserToAppPayment_Output | SendAppUserToAppUserPayment_Output | SetMockAppBalance_Output | SetMockAppUserBalance_Output
export type GuestContext = {
}
export type GuestMethodInputs = EncryptionExchange_Input | GetLnurlPayInfo_Input | GetLnurlWithdrawInfo_Input | HandleLnurlAddress_Input | HandleLnurlPay_Input | HandleLnurlWithdraw_Input | Health_Input | SetMockInvoiceAsPaid_Input
Expand Down Expand Up @@ -137,6 +137,9 @@ export type GetLnurlWithdrawLink_Output = ResultError | ({ status: 'OK' } & Lnur
export type GetMigrationUpdate_Input = {rpcName:'GetMigrationUpdate', cb:(res: MigrationUpdate, err:Error|null)=> void}
export type GetMigrationUpdate_Output = ResultError | { status: 'OK' }

export type GetNPubLinkingState_Input = {rpcName:'GetNPubLinkingState', req: GetNPubLinking}
export type GetNPubLinkingState_Output = ResultError | ({ status: 'OK' } & NPubLinking)

export type GetPaymentState_Input = {rpcName:'GetPaymentState', req: GetPaymentStateRequest}
export type GetPaymentState_Output = ResultError | ({ status: 'OK' } & PaymentState)

Expand Down Expand Up @@ -277,6 +280,7 @@ export type ServerMethods = {
GetLnurlWithdrawInfo?: (req: GetLnurlWithdrawInfo_Input & {ctx: GuestContext }) => Promise<LnurlWithdrawInfoResponse>
GetLnurlWithdrawLink?: (req: GetLnurlWithdrawLink_Input & {ctx: UserContext }) => Promise<LnurlLinkResponse>
GetMigrationUpdate?: (req: GetMigrationUpdate_Input & {ctx: UserContext }) => Promise<void>
GetNPubLinkingState?: (req: GetNPubLinkingState_Input & {ctx: AppContext }) => Promise<NPubLinking>
GetPaymentState?: (req: GetPaymentState_Input & {ctx: UserContext }) => Promise<PaymentState>
GetSeed?: (req: GetSeed_Input & {ctx: AdminContext }) => Promise<LndSeed>
GetUsageMetrics?: (req: GetUsageMetrics_Input & {ctx: MetricsContext }) => Promise<UsageMetrics>
Expand Down Expand Up @@ -1263,6 +1267,24 @@ export const GetInviteTokenStateResponseValidate = (o?: GetInviteTokenStateRespo
return null
}

export type GetNPubLinking = {
user_identifier: string
}
export const GetNPubLinkingOptionalFields: [] = []
export type GetNPubLinkingOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: []
user_identifier_CustomCheck?: (v: string) => boolean
}
export const GetNPubLinkingValidate = (o?: GetNPubLinking, opts: GetNPubLinkingOptions = {}, path: string = 'GetNPubLinking::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.user_identifier !== 'string') return new Error(`${path}.user_identifier: is not a string`)
if (opts.user_identifier_CustomCheck && !opts.user_identifier_CustomCheck(o.user_identifier)) return new Error(`${path}.user_identifier: custom check failed`)

return null
}

export type GetPaymentStateRequest = {
invoice: string
}
Expand Down Expand Up @@ -1910,6 +1932,25 @@ export const MigrationUpdateValidate = (o?: MigrationUpdate, opts: MigrationUpda
return null
}

export type NPubLinking = {
state: NPubLinking_state
}
export const NPubLinkingOptionalFields: [] = []
export type NPubLinkingOptions = OptionsBaseMessage & {
checkOptionalsAreSet?: []
state_Options?: NPubLinking_stateOptions
}
export const NPubLinkingValidate = (o?: NPubLinking, opts: NPubLinkingOptions = {}, path: string = 'NPubLinking::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')

const stateErr = NPubLinking_stateValidate(o.state, opts.state_Options, `${path}.state`)
if (stateErr !== null) return stateErr


return null
}

export type NewAddressRequest = {
addressType: AddressType
}
Expand Down Expand Up @@ -2982,6 +3023,50 @@ export const LiveDebitRequest_debitValidate = (o?: LiveDebitRequest_debit, opts:
if (typeof o.invoice !== 'string') return new Error(`${path}.invoice: is not a string`)
if (opts.invoice_CustomCheck && !opts.invoice_CustomCheck(o.invoice)) return new Error(`${path}.invoice: custom check failed`)

break
default:
return new Error(path + ': unknown type '+ stringType)
}
return null
}
export enum NPubLinking_state_type {
LINKED_NPUB = 'linked_npub',
LINKING_TOKEN = 'linking_token',
UNLINKED = 'unlinked',
}
export const enumCheckNPubLinking_state_type = (e?: NPubLinking_state_type): boolean => {
for (const v in NPubLinking_state_type) if (e === v) return true
return false
}
export type NPubLinking_state =
{type:NPubLinking_state_type.LINKED_NPUB, linked_npub:string}|
{type:NPubLinking_state_type.LINKING_TOKEN, linking_token:string}|
{type:NPubLinking_state_type.UNLINKED, unlinked:Empty}

export type NPubLinking_stateOptions = {
linked_npub_CustomCheck?: (v: string) => boolean
linking_token_CustomCheck?: (v: string) => boolean
unlinked_Options?: EmptyOptions
}
export const NPubLinking_stateValidate = (o?: NPubLinking_state, opts:NPubLinking_stateOptions = {}, path: string = 'NPubLinking_state::root.'): Error | null => {
if (typeof o !== 'object' || o === null) return new Error(path + ': object is not an instance of an object or is null')
const stringType: string = o.type
switch (o.type) {
case NPubLinking_state_type.LINKED_NPUB:
if (typeof o.linked_npub !== 'string') return new Error(`${path}.linked_npub: is not a string`)
if (opts.linked_npub_CustomCheck && !opts.linked_npub_CustomCheck(o.linked_npub)) return new Error(`${path}.linked_npub: custom check failed`)

break
case NPubLinking_state_type.LINKING_TOKEN:
if (typeof o.linking_token !== 'string') return new Error(`${path}.linking_token: is not a string`)
if (opts.linking_token_CustomCheck && !opts.linking_token_CustomCheck(o.linking_token)) return new Error(`${path}.linking_token: custom check failed`)

break
case NPubLinking_state_type.UNLINKED:
const unlinkedErr = EmptyValidate(o.unlinked, opts.unlinked_Options, `${path}.unlinked`)
if (unlinkedErr !== null) return unlinkedErr


break
default:
return new Error(path + ': unknown type '+ stringType)
Expand Down
9 changes: 7 additions & 2 deletions proto/service/methods.proto
Original file line number Diff line number Diff line change
Expand Up @@ -318,14 +318,19 @@ service LightningPub {
option (http_method) = "post";
option (http_route) = "/api/app/mock/blance/set";
}
rpc GetNPubLinkingState(structs.GetNPubLinking) returns (structs.NPubLinking) {
option (auth_type) = "App";
option (http_method) = "post";
option (http_route) = "/api/app/user/npub/token";
}
rpc RequestNPubLinkingToken(structs.RequestNPubLinkingTokenRequest) returns (structs.RequestNPubLinkingTokenResponse) {
option (auth_type) = "App";
option(http_method) = "post";
option (http_method) = "post";
option (http_route) = "/api/app/user/npub/token";
}
rpc ResetNPubLinkingToken(structs.RequestNPubLinkingTokenRequest) returns (structs.RequestNPubLinkingTokenResponse) {
option (auth_type) = "App";
option(http_method) = "post";
option (http_method) = "post";
option (http_route) = "/api/app/user/npub/token/reset";
}
// </App>
Expand Down
12 changes: 12 additions & 0 deletions proto/service/structs.proto
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,18 @@ message RelaysMigration {
repeated string relays = 1;
}

message GetNPubLinking {
string user_identifier = 1;
}

message NPubLinking {
oneof state {
Empty unlinked = 1;
string linked_npub = 2;
string linking_token = 3;
}
}


message RequestNPubLinkingTokenRequest {
string user_identifier = 1;
Expand Down
15 changes: 15 additions & 0 deletions src/services/main/applicationManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type NsecLinkingData = {
expiry: number
}
export default class {

storage: Storage
settings: MainSettings
paymentManager: PaymentManager
Expand Down Expand Up @@ -242,6 +243,20 @@ export default class {
const user = await this.storage.applicationStorage.GetApplicationUser(app, req.user_identifier)
return this.paymentManager.GetLnurlPayInfoFromUser(user.user.user_id, app, { baseUrl: req.base_url_override })
}

async GetNPubLinkingState(app_id: string, req: Types.GetNPubLinking): Promise<Types.NPubLinking> {
const app = await this.storage.applicationStorage.GetApplication(app_id);
const user = await this.storage.applicationStorage.GetApplicationUser(app, req.user_identifier);
const linking = Object.entries(this.nPubLinkingTokens).find(([_, data]) => data.serialId === user.serial_id)
if (linking) {
return { state: { type: Types.NPubLinking_state_type.LINKING_TOKEN, linking_token: linking[0] } }
}
if (user.nostr_public_key) {
return { state: { type: Types.NPubLinking_state_type.LINKED_NPUB, linked_npub: user.nostr_public_key } }
}
return { state: { type: Types.NPubLinking_state_type.UNLINKED, unlinked: {} } }
}

async RequestNPubLinkingToken(appId: string, req: Types.RequestNPubLinkingTokenRequest, reset: boolean): Promise<Types.RequestNPubLinkingTokenResponse> {
const app = await this.storage.applicationStorage.GetApplication(appId);
const user = await this.storage.applicationStorage.GetApplicationUser(app, req.user_identifier);
Expand Down
7 changes: 7 additions & 0 deletions src/services/serverMethods/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,13 @@ export default (mainHandler: Main): Types.ServerMethods => {
},
GetMigrationUpdate: async ({ ctx, cb }) => {
},
GetNPubLinkingState: async ({ ctx, req }) => {
const err = Types.GetNPubLinkingValidate(req, {
user_identifier_CustomCheck: userIdentifier => userIdentifier !== '',
})
if (err != null) throw new Error(err.message)
return mainHandler.applicationManager.GetNPubLinkingState(ctx.app_id, req)
},
RequestNPubLinkingToken: async ({ ctx, req }) => {
const err = Types.RequestNPubLinkingTokenRequestValidate(req, {
user_identifier_CustomCheck: userIdentifier => userIdentifier !== '',
Expand Down

0 comments on commit 24e0c67

Please sign in to comment.