Skip to content

Commit 3db2dc9

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

File tree

4 files changed

+271
-2
lines changed

4 files changed

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

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)