diff --git a/lib/api/index.ts b/lib/api/index.ts index 67baf93..17f76a0 100644 --- a/lib/api/index.ts +++ b/lib/api/index.ts @@ -2,3 +2,4 @@ export { default as LndApi } from './lnd'; export { default as LoopApi } from './loop'; export { default as PoolApi } from './pool'; export { default as FaradayApi } from './faraday'; +export { default as LitApi } from './lit'; diff --git a/lib/api/lit.ts b/lib/api/lit.ts new file mode 100644 index 0000000..eed4fa8 --- /dev/null +++ b/lib/api/lit.ts @@ -0,0 +1,19 @@ +import { Autopilot, Firewall, Sessions } from '../types/proto/litrpc'; +import { serviceNames as sn } from '../types/proto/schema'; + +/** + * An API wrapper to communicate with the LiT node via GRPC + */ +class LitApi { + autopilot: Autopilot; + firewall: Firewall; + sessions: Sessions; + + constructor(createRpc: Function, lnc: any) { + this.autopilot = createRpc(sn.litrpc.Autopilot, lnc); + this.firewall = createRpc(sn.litrpc.Firewall, lnc); + this.sessions = createRpc(sn.litrpc.Sessions, lnc); + } +} + +export default LitApi; diff --git a/lib/index.ts b/lib/index.ts index 6915630..fcf6b2a 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,4 +1,4 @@ export * from './types/proto'; export { camelKeysToSnake, isObject, snakeKeysToCamel } from './util/objects'; -export { LndApi, LoopApi, PoolApi, FaradayApi } from './api'; +export { LndApi, LoopApi, PoolApi, FaradayApi, LitApi } from './api'; export { subscriptionMethods } from './types/proto/schema'; diff --git a/lib/types/proto/index.ts b/lib/types/proto/index.ts index 085ecbe..4a77191 100644 --- a/lib/types/proto/index.ts +++ b/lib/types/proto/index.ts @@ -1,4 +1,5 @@ import * as frdrpc from './frdrpc'; +import * as litrpc from './litrpc'; import * as autopilotrpc from './autopilotrpc'; import * as chainrpc from './chainrpc'; import * as invoicesrpc from './invoicesrpc'; @@ -10,4 +11,4 @@ import * as watchtowerrpc from './watchtowerrpc'; import * as wtclientrpc from './wtclientrpc'; import * as looprpc from './looprpc'; import * as poolrpc from './poolrpc'; -export { frdrpc, autopilotrpc, chainrpc, invoicesrpc, lnrpc, routerrpc, signrpc, walletrpc, watchtowerrpc, wtclientrpc, looprpc, poolrpc }; \ No newline at end of file +export { frdrpc, litrpc, autopilotrpc, chainrpc, invoicesrpc, lnrpc, routerrpc, signrpc, walletrpc, watchtowerrpc, wtclientrpc, looprpc, poolrpc }; \ No newline at end of file diff --git a/lib/types/proto/lit/firewall.ts b/lib/types/proto/lit/firewall.ts new file mode 100644 index 0000000..9efd070 --- /dev/null +++ b/lib/types/proto/lit/firewall.ts @@ -0,0 +1,165 @@ +/* eslint-disable */ +export enum ActionState { + /** STATE_UNKNOWN - No state was assigned to the action. This should never be the case. */ + STATE_UNKNOWN = 'STATE_UNKNOWN', + /** + * STATE_PENDING - Pending means that the request resulting in the action being created + * came through but that no response came back from the appropriate backend. + * This means that the Action is either still being processed or that it + * did not successfully complete. + */ + STATE_PENDING = 'STATE_PENDING', + /** STATE_DONE - Done means that the action successfully completed. */ + STATE_DONE = 'STATE_DONE', + /** STATE_ERROR - Error means that the Action did not successfully complete. */ + STATE_ERROR = 'STATE_ERROR', + UNRECOGNIZED = 'UNRECOGNIZED' +} + +export interface PrivacyMapConversionRequest { + /** + * If set to true, then the input string will be taken as the real value and + * the response will the the pseudo value it if exists. Otherwise, the input + * string will be assumed to be the pseudo value. + */ + realToPseudo: boolean; + /** The session ID under which to search for the real-pseudo pair. */ + sessionId: Uint8Array | string; + /** The input to be converted into the real or pseudo value. */ + input: string; +} + +export interface PrivacyMapConversionResponse { + /** The resulting real or pseudo output. */ + output: string; +} + +export interface ListActionsRequest { + /** + * The feature name which the filter the actions by. If left empty, all feature + * actions will be returned. + */ + featureName: string; + /** + * The actor name to filter on. If left empty, all actor actions will be + * returned. + */ + actorName: string; + /** + * The method name to filter on. If left empty, actions for any method will be + * returned. + */ + methodName: string; + /** + * The action state to filter on. If set to zero, actions for any state will + * be returned. + */ + state: ActionState; + /** + * The index of an action that will be used as the start of a query to + * determine which actions should be returned in the response. + */ + indexOffset: string; + /** The max number of actions to return in the response to this query. */ + maxNumActions: string; + /** + * If set, the actions returned will result from seeking backwards from the + * specified index offset. This can be used to paginate backwards. + */ + reversed: boolean; + /** + * Set to true if the total number of all actions that match the given filters + * should be counted and returned in the request. Note that setting this will + * significantly decrease the performance of the query if there are many + * actions in the db. + */ + countTotal: boolean; + /** + * The session ID to filter on. If left empty, actions for any session will + * be returned. + */ + sessionId: Uint8Array | string; + /** + * If specified, then only actions created after the given timestamp will be + * considered. + */ + startTimestamp: string; + /** + * If specified, then only actions created before the given timestamp will be + * considered. + */ + endTimestamp: string; +} + +export interface ListActionsResponse { + /** A list of actions performed by the autopilot server. */ + actions: Action[]; + /** + * The index of the last item in the set of returned actions. This can be used + * to seek further, pagination style. + */ + lastIndexOffset: string; + /** + * The total number of actions that matched the filter in the request. It is + * only set if count_total was set in the request. + */ + totalCount: string; +} + +export interface Action { + /** The name of the actor that initiated the action. */ + actorName: string; + /** The name of the feature that triggered the action. */ + featureName: string; + /** A human readable reason that the action was performed. */ + trigger: string; + /** + * A human readable string describing the intended outcome successfully + * performing the action. + */ + intent: string; + /** Structured info added by the action performer. */ + structuredJsonData: string; + /** The URI of the method called. */ + rpcMethod: string; + /** The parameters of the method call in compact json form. */ + rpcParamsJson: string; + /** The unix timestamp in seconds at which the action was attempted. */ + timestamp: string; + /** The action state. See ActionState for the meaning of each state. */ + state: ActionState; + /** + * If the state is Error, then this string will show the human readable reason + * for why the action errored out. + */ + errorReason: string; + /** The ID of the session under which the action was performed. */ + sessionId: Uint8Array | string; +} + +export interface Firewall { + listActions(request?: DeepPartial): Promise; + privacyMapConversion( + request?: DeepPartial + ): Promise; +} + +type Builtin = + | Date + | Function + | Uint8Array + | string + | number + | boolean + | undefined; + +type DeepPartial = T extends Builtin + ? T + : T extends Array + ? Array> + : T extends ReadonlyArray + ? ReadonlyArray> + : T extends {} + ? { [K in keyof T]?: DeepPartial } + : Partial; + \ No newline at end of file diff --git a/lib/types/proto/lit/lit-autopilot.ts b/lib/types/proto/lit/lit-autopilot.ts new file mode 100644 index 0000000..9205492 --- /dev/null +++ b/lib/types/proto/lit/lit-autopilot.ts @@ -0,0 +1,158 @@ +/* eslint-disable */ +import type { + RulesMap, + Session, + RuleValue, + MacaroonPermission +} from './lit-sessions'; + +export interface AddAutopilotSessionRequest { + /** A human readable label to assign to the session. */ + label: string; + /** The unix timestamp at which this session should be revoked. */ + expiryTimestampSeconds: string; + /** The address of the mailbox server to connect to for this session. */ + mailboxServerAddr: string; + /** Set to true if tls should be skipped for when connecting to the mailbox. */ + devServer: boolean; + /** + * The features that the session should subscribe to. Each feature maps to + * a FeatureConfig that should be applied to that feature. + */ + features: { [key: string]: FeatureConfig }; + /** + * Rules that apply to the entire session. By default, no rules will apply + * to the entire session. + */ + sessionRules: RulesMap | undefined; + /** Set to true of the session should not make use of the privacy mapper. */ + noPrivacyMapper: boolean; +} + +export interface AddAutopilotSessionRequest_FeaturesEntry { + key: string; + value: FeatureConfig | undefined; +} + +export interface FeatureConfig { + /** + * The RulesMap acts as an override map. In other words, by default the rules + * values recommended by the Auto Pilot server will be used but the RulesMap + * can be used to override the defaults. + */ + rules: RulesMap | undefined; + /** Serialised configuration for the feature. */ + config: Uint8Array | string; +} + +export interface ListAutopilotSessionsRequest {} + +export interface ListAutopilotSessionsResponse { + /** A list of the Autopilot sessions. */ + sessions: Session[]; +} + +export interface AddAutopilotSessionResponse { + /** Details of the session that was just created. */ + session: Session | undefined; +} + +export interface ListAutopilotFeaturesRequest {} + +export interface ListAutopilotFeaturesResponse { + /** A map of feature names to Feature objects describing the feature. */ + features: { [key: string]: Feature }; +} + +export interface ListAutopilotFeaturesResponse_FeaturesEntry { + key: string; + value: Feature | undefined; +} + +export interface RevokeAutopilotSessionRequest { + localPublicKey: Uint8Array | string; +} + +export interface RevokeAutopilotSessionResponse {} + +export interface Feature { + /** Name is the name of the Autopilot feature. */ + name: string; + /** A human readable description of what the feature offers. */ + description: string; + /** + * A map of rules that make sense for this feature. Each rule is accompanied + * with appropriate default values for the feature along with minimum and + * maximum values for the rules. + */ + rules: { [key: string]: RuleValues }; + /** A list of URI permissions required by the feature. */ + permissionsList: Permissions[]; + /** + * A boolean indicating if the user would need to upgrade their Litd version in + * order to subscribe to the Autopilot feature. This will be true if the + * feature rules set contains a rule that Litd is unaware of. + */ + requiresUpgrade: boolean; +} + +export interface Feature_RulesEntry { + key: string; + value: RuleValues | undefined; +} + +export interface RuleValues { + /** Whether or not the users version of Litd is aware of this rule. */ + known: boolean; + /** + * The default values for the rule that the Autopilot server recommends for + * the associated feature. + */ + defaults: RuleValue | undefined; + /** The minimum sane value for this rule for the associated feature. */ + minValue: RuleValue | undefined; + /** The maximum sane value for this rule for the associated feature. */ + maxValue: RuleValue | undefined; +} + +export interface Permissions { + /** The URI in question. */ + method: string; + /** A list of the permissions required for this method. */ + operations: MacaroonPermission[]; +} + +export interface Autopilot { + listAutopilotFeatures( + request?: DeepPartial + ): Promise; + addAutopilotSession( + request?: DeepPartial + ): Promise; + listAutopilotSessions( + request?: DeepPartial + ): Promise; + revokeAutopilotSession( + request?: DeepPartial + ): Promise; +} + +type Builtin = + | Date + | Function + | Uint8Array + | string + | number + | boolean + | undefined; + +type DeepPartial = T extends Builtin + ? T + : T extends Array + ? Array> + : T extends ReadonlyArray + ? ReadonlyArray> + : T extends {} + ? { [K in keyof T]?: DeepPartial } + : Partial; + \ No newline at end of file diff --git a/lib/types/proto/lit/lit-sessions.ts b/lib/types/proto/lit/lit-sessions.ts new file mode 100644 index 0000000..3a42068 --- /dev/null +++ b/lib/types/proto/lit/lit-sessions.ts @@ -0,0 +1,222 @@ +/* eslint-disable */ +export enum SessionType { + TYPE_MACAROON_READONLY = 'TYPE_MACAROON_READONLY', + TYPE_MACAROON_ADMIN = 'TYPE_MACAROON_ADMIN', + TYPE_MACAROON_CUSTOM = 'TYPE_MACAROON_CUSTOM', + TYPE_UI_PASSWORD = 'TYPE_UI_PASSWORD', + TYPE_AUTOPILOT = 'TYPE_AUTOPILOT', + TYPE_MACAROON_ACCOUNT = 'TYPE_MACAROON_ACCOUNT', + UNRECOGNIZED = 'UNRECOGNIZED' +} + +export enum SessionState { + STATE_CREATED = 'STATE_CREATED', + STATE_IN_USE = 'STATE_IN_USE', + STATE_REVOKED = 'STATE_REVOKED', + STATE_EXPIRED = 'STATE_EXPIRED', + UNRECOGNIZED = 'UNRECOGNIZED' +} + +export interface AddSessionRequest { + label: string; + sessionType: SessionType; + expiryTimestampSeconds: string; + mailboxServerAddr: string; + devServer: boolean; + macaroonCustomPermissions: MacaroonPermission[]; + accountId: string; +} + +export interface MacaroonPermission { + /** + * The entity a permission grants access to. If a entity is set to the + * "uri" keyword then the action entry should be one of the special cases + * described in the comment for action. + */ + entity: string; + /** + * The action that is granted. If entity is set to "uri", then action must + * be set to either: + * - a particular URI to which access should be granted. + * - a URI regex, in which case access will be granted to each URI that + * matches the regex. + * - the "***readonly***" keyword. This will result in the access being + * granted to all read-only endpoints. + */ + action: string; +} + +export interface AddSessionResponse { + session: Session | undefined; +} + +export interface Session { + id: Uint8Array | string; + label: string; + sessionState: SessionState; + sessionType: SessionType; + expiryTimestampSeconds: string; + mailboxServerAddr: string; + devServer: boolean; + pairingSecret: Uint8Array | string; + pairingSecretMnemonic: string; + localPublicKey: Uint8Array | string; + remotePublicKey: Uint8Array | string; + createdAt: string; + macaroonRecipe: MacaroonRecipe | undefined; + accountId: string; + autopilotFeatureInfo: { [key: string]: RulesMap }; + /** + * The unix timestamp indicating the time at which the session was revoked. + * Note that this field has not been around since the beginning and so it + * could be the case that a session has been revoked but that this field + * will not have been set for that session. Therefore, it is suggested that + * readers should not assume that if this field is zero that the session is + * not revoked. Readers should instead first check the session_state field. + */ + revokedAt: string; +} + +export interface Session_AutopilotFeatureInfoEntry { + key: string; + value: RulesMap | undefined; +} + +export interface MacaroonRecipe { + permissions: MacaroonPermission[]; + caveats: string[]; +} + +export interface ListSessionsRequest {} + +export interface ListSessionsResponse { + sessions: Session[]; +} + +export interface RevokeSessionRequest { + localPublicKey: Uint8Array | string; +} + +export interface RevokeSessionResponse {} + +export interface RulesMap { + /** + * A map of rule name to RuleValue. The RuleValue should be parsed based on + * the name of the rule. + */ + rules: { [key: string]: RuleValue }; +} + +export interface RulesMap_RulesEntry { + key: string; + value: RuleValue | undefined; +} + +export interface RuleValue { + rateLimit: RateLimit | undefined; + chanPolicyBounds: ChannelPolicyBounds | undefined; + historyLimit: HistoryLimit | undefined; + offChainBudget: OffChainBudget | undefined; + onChainBudget: OnChainBudget | undefined; + sendToSelf: SendToSelf | undefined; + channelRestrict: ChannelRestrict | undefined; + peerRestrict: PeerRestrict | undefined; +} + +export interface RateLimit { + /** The rate limit for read-only calls. */ + readLimit: Rate | undefined; + /** The rate limit for write/execution calls. */ + writeLimit: Rate | undefined; +} + +export interface Rate { + /** The number of times a call is allowed in num_hours number of hours. */ + iterations: number; + /** The number of hours in which the iterations count takes place over. */ + numHours: number; +} + +export interface HistoryLimit { + /** + * The absolute unix timestamp in seconds before which no information should + * be shared. This should only be set if duration is not set. + */ + startTime: string; + /** + * The maximum relative duration in seconds that a request is allowed to query + * for. This should only be set if start_time is not set. + */ + duration: string; +} + +export interface ChannelPolicyBounds { + /** The minimum base fee in msat that the autopilot can set for a channel. */ + minBaseMsat: string; + /** The maximum base fee in msat that the autopilot can set for a channel. */ + maxBaseMsat: string; + /** The minimum ppm fee in msat that the autopilot can set for a channel. */ + minRatePpm: number; + /** The maximum ppm fee in msat that the autopilot can set for a channel. */ + maxRatePpm: number; + /** The minimum cltv delta that the autopilot may set for a channel. */ + minCltvDelta: number; + /** The maximum cltv delta that the autopilot may set for a channel. */ + maxCltvDelta: number; + /** The minimum htlc msat that the autopilot may set for a channel. */ + minHtlcMsat: string; + /** The maximum htlc msat that the autopilot may set for a channel. */ + maxHtlcMsat: string; +} + +export interface OffChainBudget { + maxAmtMsat: string; + maxFeesMsat: string; +} + +export interface OnChainBudget { + absoluteAmtSats: string; + maxSatPerVByte: string; +} + +export interface SendToSelf {} + +export interface ChannelRestrict { + channelIds: string[]; +} + +export interface PeerRestrict { + peerIds: string[]; +} + +/** + * Sessions is a service that gives access to the core functionalities of the + * daemon's session system. + */ +export interface Sessions { + addSession(request?: DeepPartial): Promise; + listSessions(request?: DeepPartial): Promise; + revokeSession( + request?: DeepPartial + ): Promise; +} + +type Builtin = + | Date + | Function + | Uint8Array + | string + | number + | boolean + | undefined; + +type DeepPartial = T extends Builtin + ? T + : T extends Array + ? Array> + : T extends ReadonlyArray + ? ReadonlyArray> + : T extends {} + ? { [K in keyof T]?: DeepPartial } + : Partial; + \ No newline at end of file diff --git a/lib/types/proto/litrpc.ts b/lib/types/proto/litrpc.ts new file mode 100644 index 0000000..3addfce --- /dev/null +++ b/lib/types/proto/litrpc.ts @@ -0,0 +1,3 @@ +export * from './lit/firewall'; +export * from './lit/lit-autopilot'; +export * from './lit/lit-sessions'; \ No newline at end of file diff --git a/lib/types/proto/schema.ts b/lib/types/proto/schema.ts index 5704c50..867ca8a 100644 --- a/lib/types/proto/schema.ts +++ b/lib/types/proto/schema.ts @@ -4,7 +4,7 @@ // Collection of service names to avoid having to use magic strings for // the RPC services. If anything gets renamed in the protos, it'll // produce a compiler error - export const serviceNames = {"frdrpc":{"FaradayServer":"frdrpc.FaradayServer"},"autopilotrpc":{"Autopilot":"autopilotrpc.Autopilot"},"chainrpc":{"ChainNotifier":"chainrpc.ChainNotifier"},"invoicesrpc":{"Invoices":"invoicesrpc.Invoices"},"lnrpc":{"Lightning":"lnrpc.Lightning","WalletUnlocker":"lnrpc.WalletUnlocker"},"routerrpc":{"Router":"routerrpc.Router"},"signrpc":{"Signer":"signrpc.Signer"},"walletrpc":{"WalletKit":"walletrpc.WalletKit"},"watchtowerrpc":{"Watchtower":"watchtowerrpc.Watchtower"},"wtclientrpc":{"WatchtowerClient":"wtclientrpc.WatchtowerClient"},"looprpc":{"SwapClient":"looprpc.SwapClient","Debug":"looprpc.Debug"},"poolrpc":{"ChannelAuctioneer":"poolrpc.ChannelAuctioneer","HashMail":"poolrpc.HashMail","Trader":"poolrpc.Trader"}}; + export const serviceNames = {"frdrpc":{"FaradayServer":"frdrpc.FaradayServer"},"litrpc":{"Firewall":"litrpc.Firewall","Autopilot":"litrpc.Autopilot","Sessions":"litrpc.Sessions"},"autopilotrpc":{"Autopilot":"autopilotrpc.Autopilot"},"chainrpc":{"ChainNotifier":"chainrpc.ChainNotifier"},"invoicesrpc":{"Invoices":"invoicesrpc.Invoices"},"lnrpc":{"Lightning":"lnrpc.Lightning","WalletUnlocker":"lnrpc.WalletUnlocker"},"routerrpc":{"Router":"routerrpc.Router"},"signrpc":{"Signer":"signrpc.Signer"},"walletrpc":{"WalletKit":"walletrpc.WalletKit"},"watchtowerrpc":{"Watchtower":"watchtowerrpc.Watchtower"},"wtclientrpc":{"WatchtowerClient":"wtclientrpc.WatchtowerClient"},"looprpc":{"SwapClient":"looprpc.SwapClient","Debug":"looprpc.Debug"},"poolrpc":{"ChannelAuctioneer":"poolrpc.ChannelAuctioneer","HashMail":"poolrpc.HashMail","Trader":"poolrpc.Trader"}}; // This array contains the list of methods that are server streaming. It is // used to determine if the Proxy should call 'request' or 'subscribe'. The diff --git a/package.json b/package.json index b76493f..99f9b53 100644 --- a/package.json +++ b/package.json @@ -9,13 +9,14 @@ "loop_release_tag": "v0.21.0-beta", "pool_release_tag": "v0.6.1-beta", "faraday_release_tag": "v0.2.9-alpha", + "lit_release_tag": "v0.8.6-alpha", "protoc_version": "21.9" }, "scripts": { "build": "NODE_ENV=production webpack", "dev": "webpack --watch --stats-error-details", - "update-protos": "sh scripts/update_protos.sh ${npm_package_config_lnd_release_tag} ${npm_package_config_loop_release_tag} ${npm_package_config_pool_release_tag} ${npm_package_config_faraday_release_tag}", - "generate": "sh scripts/generate_types.sh ${npm_package_config_lnd_release_tag} ${npm_package_config_loop_release_tag} ${npm_package_config_pool_release_tag} ${npm_package_config_faraday_release_tag} ${npm_package_config_protoc_version}", + "update-protos": "sh scripts/update_protos.sh ${npm_package_config_lnd_release_tag} ${npm_package_config_loop_release_tag} ${npm_package_config_pool_release_tag} ${npm_package_config_faraday_release_tag} ${npm_package_config_lit_release_tag}", + "generate": "sh scripts/generate_types.sh ${npm_package_config_lnd_release_tag} ${npm_package_config_loop_release_tag} ${npm_package_config_pool_release_tag} ${npm_package_config_faraday_release_tag} ${npm_package_config_lit_release_tag} ${npm_package_config_protoc_version}", "prettier": "prettier --check '**/*.ts*'", "prettier-write": "prettier --check --write '**/*.ts*'", "lint": "tslint -p tsconfig.json", diff --git a/protos/lit/v0.8.6-alpha/firewall.proto b/protos/lit/v0.8.6-alpha/firewall.proto new file mode 100644 index 0000000..8c5b18e --- /dev/null +++ b/protos/lit/v0.8.6-alpha/firewall.proto @@ -0,0 +1,209 @@ +syntax = "proto3"; + +package litrpc; + +option go_package = "github.com/lightninglabs/lightning-terminal/litrpc"; + +service Firewall { + rpc ListActions (ListActionsRequest) returns (ListActionsResponse); + rpc PrivacyMapConversion (PrivacyMapConversionRequest) + returns (PrivacyMapConversionResponse); +} + +message PrivacyMapConversionRequest { + /* + If set to true, then the input string will be taken as the real value and + the response will the the pseudo value it if exists. Otherwise, the input + string will be assumed to be the pseudo value. + */ + bool real_to_pseudo = 1; + + /* + The session ID under which to search for the real-pseudo pair. + */ + bytes session_id = 2; + + /* + The input to be converted into the real or pseudo value. + */ + string input = 3; +} + +message PrivacyMapConversionResponse { + /* + The resulting real or pseudo output. + */ + string output = 1; +} + +message ListActionsRequest { + /* + The feature name which the filter the actions by. If left empty, all feature + actions will be returned. + */ + string feature_name = 1; + + /* + The actor name to filter on. If left empty, all actor actions will be + returned. + */ + string actor_name = 2; + + /* + The method name to filter on. If left empty, actions for any method will be + returned. + */ + string method_name = 3; + + /* + The action state to filter on. If set to zero, actions for any state will + be returned. + */ + ActionState state = 4; + + /* + The index of an action that will be used as the start of a query to + determine which actions should be returned in the response. + */ + uint64 index_offset = 5; + + /* + The max number of actions to return in the response to this query. + */ + uint64 max_num_actions = 6; + + /* + If set, the actions returned will result from seeking backwards from the + specified index offset. This can be used to paginate backwards. + */ + bool reversed = 7; + + /* + Set to true if the total number of all actions that match the given filters + should be counted and returned in the request. Note that setting this will + significantly decrease the performance of the query if there are many + actions in the db. + */ + bool count_total = 8; + + /* + The session ID to filter on. If left empty, actions for any session will + be returned. + */ + bytes session_id = 9; + + /* + If specified, then only actions created after the given timestamp will be + considered. + */ + uint64 start_timestamp = 10 [jstype = JS_STRING]; + + /* + If specified, then only actions created before the given timestamp will be + considered. + */ + uint64 end_timestamp = 11 [jstype = JS_STRING]; +} + +message ListActionsResponse { + /* + A list of actions performed by the autopilot server. + */ + repeated Action actions = 1; + + /* + The index of the last item in the set of returned actions. This can be used + to seek further, pagination style. + */ + uint64 last_index_offset = 2; + + /* + The total number of actions that matched the filter in the request. It is + only set if count_total was set in the request. + */ + uint64 total_count = 3; +} + +message Action { + /* + The name of the actor that initiated the action. + */ + string actor_name = 1; + + /* + The name of the feature that triggered the action. + */ + string feature_name = 2; + + /* + A human readable reason that the action was performed. + */ + string trigger = 3; + + /* + A human readable string describing the intended outcome successfully + performing the action. + */ + string intent = 4; + + /* + Structured info added by the action performer. + */ + string structured_json_data = 5; + + /* + The URI of the method called. + */ + string rpc_method = 6; + + /* + The parameters of the method call in compact json form. + */ + string rpc_params_json = 7; + + /* + The unix timestamp in seconds at which the action was attempted. + */ + uint64 timestamp = 8 [jstype = JS_STRING]; + + /* + The action state. See ActionState for the meaning of each state. + */ + ActionState state = 9; + + /* + If the state is Error, then this string will show the human readable reason + for why the action errored out. + */ + string error_reason = 10; + + /* + The ID of the session under which the action was performed. + */ + bytes session_id = 11; +} + +enum ActionState { + /* + No state was assigned to the action. This should never be the case. + */ + STATE_UNKNOWN = 0; + + /* + Pending means that the request resulting in the action being created + came through but that no response came back from the appropriate backend. + This means that the Action is either still being processed or that it + did not successfully complete. + */ + STATE_PENDING = 1; + + /* + Done means that the action successfully completed. + */ + STATE_DONE = 2; + + /* + Error means that the Action did not successfully complete. + */ + STATE_ERROR = 3; +} \ No newline at end of file diff --git a/protos/lit/v0.8.6-alpha/lit-autopilot.proto b/protos/lit/v0.8.6-alpha/lit-autopilot.proto new file mode 100644 index 0000000..740829d --- /dev/null +++ b/protos/lit/v0.8.6-alpha/lit-autopilot.proto @@ -0,0 +1,174 @@ +syntax = "proto3"; + +import "lit-sessions.proto"; + +package litrpc; + +option go_package = "github.com/lightninglabs/lightning-terminal/litrpc"; + +service Autopilot { + rpc ListAutopilotFeatures (ListAutopilotFeaturesRequest) + returns (ListAutopilotFeaturesResponse); + + rpc AddAutopilotSession (AddAutopilotSessionRequest) + returns (AddAutopilotSessionResponse); + + rpc ListAutopilotSessions (ListAutopilotSessionsRequest) + returns (ListAutopilotSessionsResponse); + + rpc RevokeAutopilotSession (RevokeAutopilotSessionRequest) + returns (RevokeAutopilotSessionResponse); +} + +message AddAutopilotSessionRequest { + /* + A human readable label to assign to the session. + */ + string label = 1; + + /* + The unix timestamp at which this session should be revoked. + */ + uint64 expiry_timestamp_seconds = 2 [jstype = JS_STRING]; + + /* + The address of the mailbox server to connect to for this session. + */ + string mailbox_server_addr = 3; + + /* + Set to true if tls should be skipped for when connecting to the mailbox. + */ + bool dev_server = 4; + + /* + The features that the session should subscribe to. Each feature maps to + a FeatureConfig that should be applied to that feature. + */ + map features = 5; + + /* + Rules that apply to the entire session. By default, no rules will apply + to the entire session. + */ + RulesMap session_rules = 6; + + /* + Set to true of the session should not make use of the privacy mapper. + */ + bool no_privacy_mapper = 7; +} + +message FeatureConfig { + /* + The RulesMap acts as an override map. In other words, by default the rules + values recommended by the Auto Pilot server will be used but the RulesMap + can be used to override the defaults. + */ + RulesMap rules = 1; + + /* + Serialised configuration for the feature. + */ + bytes config = 2; +} + +message ListAutopilotSessionsRequest { +} + +message ListAutopilotSessionsResponse { + /* + A list of the Autopilot sessions. + */ + repeated Session sessions = 1; +} + +message AddAutopilotSessionResponse { + /* + Details of the session that was just created. + */ + Session session = 1; +} + +message ListAutopilotFeaturesRequest { +} + +message ListAutopilotFeaturesResponse { + /* + A map of feature names to Feature objects describing the feature. + */ + map features = 1; +} + +message RevokeAutopilotSessionRequest { + bytes local_public_key = 1; +} + +message RevokeAutopilotSessionResponse { +} + +message Feature { + /* + Name is the name of the Autopilot feature. + */ + string name = 1; + + /* + A human readable description of what the feature offers. + */ + string description = 2; + + /* + A map of rules that make sense for this feature. Each rule is accompanied + with appropriate default values for the feature along with minimum and + maximum values for the rules. + */ + map rules = 3; + + /* + A list of URI permissions required by the feature. + */ + repeated Permissions permissions_list = 4; + + /* + A boolean indicating if the user would need to upgrade their Litd version in + order to subscribe to the Autopilot feature. This will be true if the + feature rules set contains a rule that Litd is unaware of. + */ + bool requires_upgrade = 5; +} + +message RuleValues { + /* + Whether or not the users version of Litd is aware of this rule. + */ + bool known = 1; + + /* + The default values for the rule that the Autopilot server recommends for + the associated feature. + */ + RuleValue defaults = 2; + + /* + The minimum sane value for this rule for the associated feature. + */ + RuleValue min_value = 3; + + /* + The maximum sane value for this rule for the associated feature. + */ + RuleValue max_value = 4; +} + +message Permissions { + /* + The URI in question. + */ + string method = 1; + + /* + A list of the permissions required for this method. + */ + repeated MacaroonPermission operations = 2; +} \ No newline at end of file diff --git a/protos/lit/v0.8.6-alpha/lit-sessions.proto b/protos/lit/v0.8.6-alpha/lit-sessions.proto new file mode 100644 index 0000000..27737f3 --- /dev/null +++ b/protos/lit/v0.8.6-alpha/lit-sessions.proto @@ -0,0 +1,251 @@ +syntax = "proto3"; + +package litrpc; + +option go_package = "github.com/lightninglabs/lightning-terminal/litrpc"; + +// Sessions is a service that gives access to the core functionalities of the +// daemon's session system. +service Sessions { + rpc AddSession (AddSessionRequest) returns (AddSessionResponse); + + rpc ListSessions (ListSessionsRequest) returns (ListSessionsResponse); + + rpc RevokeSession (RevokeSessionRequest) returns (RevokeSessionResponse); +} + +enum SessionType { + TYPE_MACAROON_READONLY = 0; + TYPE_MACAROON_ADMIN = 1; + TYPE_MACAROON_CUSTOM = 2; + TYPE_UI_PASSWORD = 3; + TYPE_AUTOPILOT = 4; + TYPE_MACAROON_ACCOUNT = 5; +} + +message AddSessionRequest { + string label = 1; + + SessionType session_type = 2; + + uint64 expiry_timestamp_seconds = 3 [jstype = JS_STRING]; + + string mailbox_server_addr = 4; + + bool dev_server = 5; + + repeated MacaroonPermission macaroon_custom_permissions = 6; + + string account_id = 7; +} + +message MacaroonPermission { + // The entity a permission grants access to. If a entity is set to the + // "uri" keyword then the action entry should be one of the special cases + // described in the comment for action. + string entity = 1; + + // The action that is granted. If entity is set to "uri", then action must + // be set to either: + // - a particular URI to which access should be granted. + // - a URI regex, in which case access will be granted to each URI that + // matches the regex. + // - the "***readonly***" keyword. This will result in the access being + // granted to all read-only endpoints. + string action = 2; +} + +enum SessionState { + STATE_CREATED = 0; + STATE_IN_USE = 1; + STATE_REVOKED = 2; + STATE_EXPIRED = 3; +} + +message AddSessionResponse { + Session session = 1; +} + +message Session { + bytes id = 14; + + string label = 1; + + SessionState session_state = 2; + + SessionType session_type = 3; + + uint64 expiry_timestamp_seconds = 4 [jstype = JS_STRING]; + + string mailbox_server_addr = 5; + + bool dev_server = 6; + + bytes pairing_secret = 7; + + string pairing_secret_mnemonic = 8; + + bytes local_public_key = 9; + + bytes remote_public_key = 10; + + uint64 created_at = 11 [jstype = JS_STRING]; + + MacaroonRecipe macaroon_recipe = 12; + + string account_id = 13; + + map autopilot_feature_info = 15; + + /* + The unix timestamp indicating the time at which the session was revoked. + Note that this field has not been around since the beginning and so it + could be the case that a session has been revoked but that this field + will not have been set for that session. Therefore, it is suggested that + readers should not assume that if this field is zero that the session is + not revoked. Readers should instead first check the session_state field. + */ + uint64 revoked_at = 16 [jstype = JS_STRING]; +} + +message MacaroonRecipe { + repeated MacaroonPermission permissions = 1; + + repeated string caveats = 2; +} + +message ListSessionsRequest { +} + +message ListSessionsResponse { + repeated Session sessions = 1; +} + +message RevokeSessionRequest { + bytes local_public_key = 8; +} + +message RevokeSessionResponse { +} + +message RulesMap { + /* + A map of rule name to RuleValue. The RuleValue should be parsed based on + the name of the rule. + */ + map rules = 1; +} + +message RuleValue { + oneof value { + RateLimit rate_limit = 1; + ChannelPolicyBounds chan_policy_bounds = 2; + HistoryLimit history_limit = 3; + OffChainBudget off_chain_budget = 4; + OnChainBudget on_chain_budget = 5; + SendToSelf send_to_self = 6; + ChannelRestrict channel_restrict = 7; + PeerRestrict peer_restrict = 8; + } +} + +message RateLimit { + /* + The rate limit for read-only calls. + */ + Rate read_limit = 1; + + /* + The rate limit for write/execution calls. + */ + Rate write_limit = 2; +} + +message Rate { + /* + The number of times a call is allowed in num_hours number of hours. + */ + uint32 iterations = 1; + + /* + The number of hours in which the iterations count takes place over. + */ + uint32 num_hours = 2; +} + +message HistoryLimit { + /* + The absolute unix timestamp in seconds before which no information should + be shared. This should only be set if duration is not set. + */ + uint64 start_time = 1 [jstype = JS_STRING]; + + /* + The maximum relative duration in seconds that a request is allowed to query + for. This should only be set if start_time is not set. + */ + uint64 duration = 2 [jstype = JS_STRING]; +} + +message ChannelPolicyBounds { + /* + The minimum base fee in msat that the autopilot can set for a channel. + */ + uint64 min_base_msat = 1 [jstype = JS_STRING]; + + /* + The maximum base fee in msat that the autopilot can set for a channel. + */ + uint64 max_base_msat = 2 [jstype = JS_STRING]; + + /* + The minimum ppm fee in msat that the autopilot can set for a channel. + */ + uint32 min_rate_ppm = 3; + + /* + The maximum ppm fee in msat that the autopilot can set for a channel. + */ + uint32 max_rate_ppm = 4; + + /* + The minimum cltv delta that the autopilot may set for a channel. + */ + uint32 min_cltv_delta = 5; + + /* + The maximum cltv delta that the autopilot may set for a channel. + */ + uint32 max_cltv_delta = 6; + + /* + The minimum htlc msat that the autopilot may set for a channel. + */ + uint64 min_htlc_msat = 7 [jstype = JS_STRING]; + + /* + The maximum htlc msat that the autopilot may set for a channel. + */ + uint64 max_htlc_msat = 8 [jstype = JS_STRING]; +} + +message OffChainBudget { + uint64 max_amt_msat = 1 [jstype = JS_STRING]; + uint64 max_fees_msat = 2 [jstype = JS_STRING]; +} + +message OnChainBudget { + uint64 absolute_amt_sats = 1 [jstype = JS_STRING]; + uint64 max_sat_per_v_byte = 2 [jstype = JS_STRING]; +} + +message SendToSelf { +} + +message ChannelRestrict { + repeated uint64 channel_ids = 1 [jstype = JS_STRING]; +} + +message PeerRestrict { + repeated string peer_ids = 1; +} \ No newline at end of file diff --git a/scripts/generate_types.sh b/scripts/generate_types.sh index 4bef9b3..a946a8d 100644 --- a/scripts/generate_types.sh +++ b/scripts/generate_types.sh @@ -7,12 +7,14 @@ LND_RELEASE_TAG=$1 LOOP_RELEASE_TAG=$2 POOL_RELEASE_TAG=$3 FARADAY_RELEASE_TAG=$4 -PROTOC_VERSION=$5 +LIT_RELEASE_TAG=$5 +PROTOC_VERSION=$6 echo "LND release tag:" $LND_RELEASE_TAG echo "Loop release tag:" $LOOP_RELEASE_TAG echo "Pool release tag:" $POOL_RELEASE_TAG echo "Faraday release tag:" $FARADAY_RELEASE_TAG +echo "LiT release tag:" $LIT_RELEASE_TAG echo "Protoc version:" $PROTOC_VERSION GENERATED_TYPES_DIR=lib/types/proto @@ -104,6 +106,17 @@ protoc/bin/protoc \ $TS_PROTO_OPTIONS \ faraday.proto +echo "LiT: running protoc..." +mkdir -p "$GENERATED_TYPES_DIR/lit" +protoc/bin/protoc \ + --proto_path=protos/lit/${LIT_RELEASE_TAG} \ + --plugin=./node_modules/.bin/protoc-gen-ts_proto \ + --ts_proto_out=$GENERATED_TYPES_DIR/lit \ + $TS_PROTO_OPTIONS \ + firewall.proto \ + lit-sessions.proto \ + lit-autopilot.proto + # Temporarily generate schema files in order to provide metadata # about the services and subscription methods to the api classes SCHEMA_DIR=lib/types/schema @@ -169,6 +182,17 @@ protoc/bin/protoc \ $SCHEMA_PROTO_OPTIONS \ faraday.proto +echo "LIT: generating schema..." +mkdir -p "$SCHEMA_DIR/lit" +protoc/bin/protoc \ + --proto_path=protos/lit/${LIT_RELEASE_TAG} \ + --plugin=./node_modules/.bin/protoc-gen-ts_proto \ + --ts_proto_out=$SCHEMA_DIR/lit \ + $SCHEMA_PROTO_OPTIONS \ + firewall.proto \ + lit-sessions.proto \ + lit-autopilot.proto + # Cleanup proto directory/files rm -rf *.proto protoc diff --git a/scripts/update_protos.sh b/scripts/update_protos.sh index d2d915d..9d9bf9b 100644 --- a/scripts/update_protos.sh +++ b/scripts/update_protos.sh @@ -2,17 +2,20 @@ LND_RELEASE_TAG=$1 LOOP_RELEASE_TAG=$2 POOL_RELEASE_TAG=$3 FARADAY_RELEASE_TAG=$4 +LIT_RELEASE_TAG=$5 echo "LND release tag:" $LND_RELEASE_TAG echo "Loop release tag:" $LOOP_RELEASE_TAG echo "Pool release tag:" $POOL_RELEASE_TAG echo "Faraday release tag:" $FARADAY_RELEASE_TAG +echo "LiT release tag:" $LIT_RELEASE_TAG # RPC Servers LND_URL="https://raw.githubusercontent.com/lightningnetwork/lnd" LOOP_URL="https://raw.githubusercontent.com/lightninglabs/loop" POOL_URL="https://raw.githubusercontent.com/lightninglabs/pool" FARADAY_URL="https://raw.githubusercontent.com/lightninglabs/faraday" +LIT_URL="https://raw.githubusercontent.com/lightninglabs/lightning-terminal" curl ${LND_URL}/${LND_RELEASE_TAG}/lnrpc/lightning.proto --create-dirs -o protos/lnd/${LND_RELEASE_TAG}/lightning.proto curl ${LND_URL}/${LND_RELEASE_TAG}/lnrpc/walletunlocker.proto --create-dirs -o protos/lnd/${LND_RELEASE_TAG}/walletunlocker.proto @@ -35,3 +38,7 @@ curl ${POOL_URL}/${POOL_RELEASE_TAG}/auctioneerrpc/auctioneer.proto --create-dir curl ${POOL_URL}/${POOL_RELEASE_TAG}/auctioneerrpc/hashmail.proto --create-dirs -o protos/pool/${POOL_RELEASE_TAG}/auctioneerrpc/hashmail.proto curl ${FARADAY_URL}/${FARADAY_RELEASE_TAG}/frdrpc/faraday.proto --create-dirs -o protos/faraday/${FARADAY_RELEASE_TAG}/faraday.proto + +curl ${LIT_URL}/${LIT_RELEASE_TAG}/litrpc/firewall.proto --create-dirs -o protos/lit/${LIT_RELEASE_TAG}/firewall.proto +curl ${LIT_URL}/${LIT_RELEASE_TAG}/litrpc/lit-sessions.proto --create-dirs -o protos/lit/${LIT_RELEASE_TAG}/lit-sessions.proto +curl ${LIT_URL}/${LIT_RELEASE_TAG}/litrpc/lit-autopilot.proto --create-dirs -o protos/lit/${LIT_RELEASE_TAG}/lit-autopilot.proto diff --git a/webpack.config.js b/webpack.config.js index aa777e8..12e46c1 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -28,6 +28,7 @@ module.exports = { name: '@lightninglabs/lnc-core', type: "umd", // see https://webpack.js.org/configuration/output/#outputlibrarytype }, + globalObject: 'this', path: path.resolve(__dirname, 'dist'), }, };