Skip to content

Commit 1c3f33a

Browse files
committed
mobx: Created addSessionView, added support for custom sessions
1 parent 77bda8f commit 1c3f33a

File tree

4 files changed

+272
-2
lines changed

4 files changed

+272
-2
lines changed

app/src/store/store.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from './stores';
2121
import {
2222
AccountSectionView,
23+
AddSessionView,
2324
AppView,
2425
BatchesView,
2526
BuildSwapView,
@@ -66,6 +67,7 @@ export class Store {
6667
orderListView = new OrderListView(this);
6768
batchesView = new BatchesView(this);
6869
registerSidecarView = new RegisterSidecarView(this);
70+
addSessionView = new AddSessionView(this);
6971

7072
/** the backend api services to be used by child stores */
7173
api: {

app/src/store/stores/sessionStore.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ export default class SessionStore {
102102
type: LIT.SessionTypeMap[keyof LIT.SessionTypeMap],
103103
expiry: Date,
104104
copy = false,
105+
proxy?: string,
106+
customPermissions?: LIT.MacaroonPermission[],
105107
) {
106108
try {
107109
this._store.log.info(`submitting session with label ${label}`, {
@@ -114,9 +116,9 @@ export default class SessionStore {
114116
label,
115117
type,
116118
expiry,
117-
this.proxyServer,
119+
proxy || this.proxyServer,
118120
!IS_PROD,
119-
[],
121+
customPermissions || [],
120122
);
121123

122124
// fetch all sessions to update the store's state

app/src/store/views/addSessionView.ts

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
import { makeAutoObservable, observable } from 'mobx';
2+
import { Store } from 'store';
3+
import * as LIT from 'types/generated/lit-sessions_pb';
4+
import { MAX_DATE } from 'util/constants';
5+
6+
export default class AddSessionView {
7+
private _store: Store;
8+
9+
// A map of all the necessary URIs for each set of features
10+
private permissionMap: { [key: string]: string[] } = {
11+
openChannel: [
12+
'/lnrpc.Lightning/OpenChannel',
13+
'/lnrpc.Lightning/BatchOpenChannel',
14+
'/lnrpc.Lightning/OpenChannelSync',
15+
],
16+
closeChannel: ['/lnrpc.Lightning/CloseChannel'],
17+
setFees: [
18+
'/lnrpc.Lightning/EstimateFee',
19+
'/lnrpc.Lightning/FeeReport',
20+
'/lnrpc.Lightning/UpdateChannelPolicy',
21+
],
22+
loop: ['/looprpc.SwapClient/*'],
23+
pool: ['/poolrpc.Trader/*'],
24+
viewActivity: [
25+
'/lnrpc.Lightning/GetInfo',
26+
'/lnrpc.Lightning/SubscribeTransactions',
27+
'/lnrpc.Lightning/SubscribeChannelEvents',
28+
'/lnrpc.Lightning/ListChannels',
29+
'/lnrpc.Lightning/PendingChannels',
30+
'/lnrpc.Lightning/GetNodeInfo',
31+
'/lnrpc.Lightning/GetChanInfo',
32+
'/lnrpc.Lightning/ChannelBalance',
33+
'/lnrpc.Lightning/WalletBalance',
34+
'/lnrpc.Lightning/ForwardingHistory',
35+
],
36+
send: [
37+
'/lnrpc.Lightning/SendCoins',
38+
'/lnrpc.Lightning/SendMany',
39+
'/lnrpc.Lightning/SendPayment',
40+
'/lnrpc.Lightning/SendPaymentSync',
41+
'/lnrpc.Lightning/SendToRoute',
42+
'/lnrpc.Lightning/SendToRouteSync',
43+
],
44+
receive: [
45+
'/lnrpc.Lightning/NewAddress',
46+
'/lnrpc.Lightning/AddInvoice',
47+
'/lnrpc.Lightning/LookupInvoice',
48+
'/lnrpc.Lightning/ListInvoices',
49+
'/lnrpc.Lightning/SubscribeInvoices',
50+
],
51+
};
52+
53+
label = '';
54+
permissionType = 'admin';
55+
editing = false;
56+
permissions: { [key: string]: boolean } = {
57+
openChannel: false,
58+
closeChannel: false,
59+
setFees: false,
60+
loop: false,
61+
pool: false,
62+
viewActivity: false,
63+
send: false,
64+
receive: false,
65+
};
66+
expiration = 'never';
67+
expirationDate = '';
68+
showAdvanced = false;
69+
proxy = '';
70+
71+
constructor(store: Store) {
72+
makeAutoObservable(
73+
this,
74+
{
75+
permissions: observable.deep,
76+
},
77+
{ deep: false, autoBind: true },
78+
);
79+
80+
this._store = store;
81+
}
82+
83+
//
84+
// Private helper functions
85+
//
86+
87+
private setAllPermissions(value: boolean) {
88+
Object.keys(this.permissions).forEach(permissionName => {
89+
this.permissions[permissionName] = value;
90+
});
91+
}
92+
93+
private getMacaroonPermissions() {
94+
// Only output macaroon permissions when the session type is custom
95+
if (this.sessionType === LIT.SessionType.TYPE_MACAROON_CUSTOM) {
96+
const permissions: string[] = [];
97+
98+
// Loop over all permissions to determine which are enabled
99+
Object.entries(this.permissions).forEach(([permissionName, permissionEnabled]) => {
100+
if (permissionEnabled) {
101+
// Add all of the URIs for this permission
102+
permissions.push(...this.permissionMap[permissionName]);
103+
}
104+
});
105+
106+
// Convert all of the permission strings into MacaroonPermission objects
107+
return permissions.map(uri => {
108+
const mp = new LIT.MacaroonPermission();
109+
mp.setEntity('uri');
110+
mp.setAction(uri);
111+
return mp;
112+
});
113+
}
114+
115+
return [];
116+
}
117+
118+
//
119+
// Computed properties
120+
//
121+
122+
get sessionType() {
123+
if (this.permissionType === 'admin') {
124+
return LIT.SessionType.TYPE_MACAROON_ADMIN;
125+
} else if (this.permissionType === 'read-only') {
126+
return LIT.SessionType.TYPE_MACAROON_READONLY;
127+
}
128+
129+
return LIT.SessionType.TYPE_MACAROON_CUSTOM;
130+
}
131+
132+
get sessionDate() {
133+
// If the expiration date is a number of days
134+
if (Number.isInteger(parseInt(this.expiration))) {
135+
const expirationDate = new Date();
136+
expirationDate.setDate(expirationDate.getDate() + parseInt(this.expiration));
137+
return expirationDate;
138+
} else if (this.expiration === 'custom') {
139+
return new Date(this.expirationDate);
140+
}
141+
142+
// Default to max date for when the expiration is "never"
143+
return MAX_DATE;
144+
}
145+
146+
get sessionProxy() {
147+
if (this.proxy) {
148+
return this.proxy;
149+
}
150+
151+
return undefined;
152+
}
153+
154+
//
155+
// Actions
156+
//
157+
158+
setLabel(label: string) {
159+
this.label = label;
160+
}
161+
162+
setExpiration(expiration: string) {
163+
this.expiration = expiration;
164+
}
165+
166+
setExpirationDate(expirationDate: string) {
167+
this.expirationDate = expirationDate;
168+
}
169+
170+
setProxy(proxy: string) {
171+
this.proxy = proxy;
172+
}
173+
174+
setPermissionType(permissionType: string) {
175+
this.permissionType = permissionType;
176+
177+
switch (permissionType) {
178+
case 'admin':
179+
this.setAllPermissions(true);
180+
break;
181+
182+
case 'read-only':
183+
this.setAllPermissions(false);
184+
this.permissions.viewActivity = true;
185+
break;
186+
187+
case 'liquidity':
188+
this.setAllPermissions(false);
189+
this.permissions.setFees = true;
190+
this.permissions.loop = true;
191+
this.permissions.pool = true;
192+
break;
193+
194+
case 'payments':
195+
this.setAllPermissions(false);
196+
this.permissions.send = true;
197+
this.permissions.receive = true;
198+
break;
199+
200+
case 'custom':
201+
// We don't need to change anything, let the user customize permissions how they want
202+
break;
203+
}
204+
}
205+
206+
togglePermission(permission: string) {
207+
this.setPermissionType('custom');
208+
this.permissions[permission] = !this.permissions[permission];
209+
}
210+
211+
toggleEditing() {
212+
this.editing = !this.editing;
213+
}
214+
215+
toggleAdvanced() {
216+
this.showAdvanced = !this.showAdvanced;
217+
}
218+
219+
cancel() {
220+
this.label = '';
221+
this.permissionType = 'admin';
222+
this.editing = false;
223+
this.setAllPermissions(false);
224+
this.expiration = 'never';
225+
this.showAdvanced = false;
226+
}
227+
228+
//
229+
// Async Actions
230+
//
231+
232+
async handleSubmit() {
233+
if (this.permissionType === 'custom') {
234+
this._store.settingsStore.sidebarVisible = false;
235+
this._store.router.push('/connect/custom');
236+
} else {
237+
const session = await this._store.sessionStore.addSession(
238+
this.label,
239+
this.sessionType,
240+
MAX_DATE,
241+
true,
242+
);
243+
244+
if (session) {
245+
this.cancel();
246+
}
247+
}
248+
}
249+
250+
async handleCustomSubmit() {
251+
const session = await this._store.sessionStore.addSession(
252+
this.label,
253+
this.sessionType,
254+
this.sessionDate,
255+
true,
256+
this.sessionProxy,
257+
this.getMacaroonPermissions(),
258+
);
259+
260+
if (session) {
261+
this.cancel();
262+
this._store.router.push('/connect');
263+
}
264+
}
265+
}

app/src/store/views/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ export { default as OrderListView } from './orderListView';
1010
export { default as LeaseView } from './leaseView';
1111
export { default as BatchesView } from './batchesView';
1212
export { default as RegisterSidecarView } from './registerSidecarView';
13+
export { default as AddSessionView } from './addSessionView';

0 commit comments

Comments
 (0)