Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] feat: Deezy.io Integration #124

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
}
},
"dependencies": {
"@lily-technologies/lnrpc": "^0.14.1-beta.14",
"@lily-technologies/lnrpc": "^0.15.4-beta.2",
"@lily/shared-server": "1.3.0",
"@lily/types": "1.3.0",
"axios": "^0.24.0",
Expand Down
25 changes: 24 additions & 1 deletion apps/electron/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import {
createTransactionTable,
addTransactionDescription,
getTransactionDescription,
dbConnect
dbConnect,
generateMacaroonPermissions
} from '@lily/shared-server';

import {
Expand Down Expand Up @@ -761,6 +762,28 @@ ipcMain.handle('/get-transaction-description', async (event, args) => {
}
});

ipcMain.handle('/bake-macaroon', async (event, args) => {
const macaroon = LightningDataProvider.bakeMacaroon({
permissions: generateMacaroonPermissions(),
rootKeyId: 4552625,
allowExternalPermissions: false
});
const url = ''; // TODO: replace with deezy.io endpoint
const response = await axios.post(url, {
macaroon
});

return Promise.resolve(response.data);
});

ipcMain.handle('/revoke-macaroon', async (event, args) => {
const { rootKeyId } = args;
const { deleted } = await LightningDataProvider.revokeMacaroon(rootKeyId);
// TODO: does this need to make a network request to deezy.io?
const url = ''; // TODO: replace with endpoint
return Promise.resolve(deleted);
});

// Log both at dev console and at running node console instance
function logEverywhere(s: string) {
console.log(s);
Expand Down
2 changes: 1 addition & 1 deletion apps/express/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"@lily-technologies/lnrpc": "^0.14.1-beta.14",
"@lily-technologies/lnrpc": "^0.15.4-beta.2",
"@lily/shared-server": "1.3.0",
"@lily/types": "1.3.0",
"axios": "^0.24.0",
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@headlessui/react": "^1.6.1",
"@heroicons/react": "^1.0.3",
"@lily-technologies/ecpair": "^2.0.0",
"@lily-technologies/lnrpc": "^0.14.1-beta.14",
"@lily-technologies/lnrpc": "^0.15.4-beta.2",
"@lily/types": "1.3.0",
"@styled-icons/bootstrap": "^10.34.0",
"@styled-icons/boxicons-logos": "^10.38.0",
Expand Down
8 changes: 7 additions & 1 deletion apps/frontend/src/frontend-middleware/BasePlatform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import type {
QueryRoutesResponse,
GetInfoResponse,
ChannelBalanceResponse,
SendPaymentRequest
SendPaymentRequest,
BakeMacaroonResponse,
DeleteMacaroonIDRequest,
DeleteMacaroonIDResponse
} from '@lily-technologies/lnrpc';

import { WalletInfo } from 'bitcoin-simple-rpc';
Expand Down Expand Up @@ -239,4 +242,7 @@ export abstract class BasePlatform implements PlatformInterface {

abstract addTransactionDescription(txid: string, description: string): Promise<number>;
abstract getTransactionDescription(txid: string): Promise<TransactionDescription>;

abstract bakeMacaroon(): Promise<BakeMacaroonResponse>;
abstract revokeMacaroon(): Promise<DeleteMacaroonIDResponse>;
}
15 changes: 14 additions & 1 deletion apps/frontend/src/frontend-middleware/ElectronPlatform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import type {
Invoice,
QueryRoutesRequest,
QueryRoutesResponse,
SendPaymentRequest
SendPaymentRequest,
BakeMacaroonResponse,
DeleteMacaroonIDRequest,
DeleteMacaroonIDResponse
} from '@lily-technologies/lnrpc';

import { WalletInfo } from 'bitcoin-simple-rpc';
Expand Down Expand Up @@ -351,4 +354,14 @@ export class ElectronPlatform extends BasePlatform {
});
return Promise.resolve(response);
}

async bakeMacaroon(): Promise<BakeMacaroonResponse> {
const response = await window.ipcRenderer.invoke('/bake-macaroon');
return Promise.resolve(response);
}

async revokeMacaroon(): Promise<DeleteMacaroonIDResponse> {
const { deleted } = await window.ipcRenderer.invoke('/revoke-macaroon', { rootKeyId: 4552625 });
return Promise.resolve({ deleted });
}
}
17 changes: 16 additions & 1 deletion apps/frontend/src/frontend-middleware/WebPlatform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import type {
Invoice,
QueryRoutesRequest,
QueryRoutesResponse,
SendPaymentRequest
SendPaymentRequest,
BakeMacaroonResponse,
DeleteMacaroonIDRequest,
DeleteMacaroonIDResponse
} from '@lily-technologies/lnrpc';

import { WalletInfo } from 'bitcoin-simple-rpc';
Expand Down Expand Up @@ -373,4 +376,16 @@ export class WebPlatform extends BasePlatform {
});
return Promise.resolve(data);
}

async bakeMacaroon(): Promise<BakeMacaroonResponse> {
// TODO: implement later
return { macaroon: 'abc' };
}

async revokeMacaroon(): Promise<DeleteMacaroonIDResponse> {
const { data } = await axios.post<DeleteMacaroonIDResponse>('/revoke-macaroon', {
rootKeyId: 4552625
});
return Promise.resolve(data);
}
}
116 changes: 116 additions & 0 deletions apps/frontend/src/pages/Lightning/Settings/GeneralView/DeezyToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React, { useContext, useState } from 'react';
import { Switch } from '@headlessui/react';
import { ExternalLinkIcon } from '@heroicons/react/outline';

import FlowerLoading from 'src/assets/flower-loading.svg';

import { PlatformContext } from 'src/context';

function classNames(...classes) {
return classes.filter(Boolean).join(' ');
}

export default function DeezyToggle() {
const { platform } = useContext(PlatformContext);
const [enabled, setEnabled] = useState(false);
const [isLoading, setIsLoading] = useState(false);

const toggleDeezy = async () => {
try {
setIsLoading(true);
if (enabled) {
const macaroon = await platform.bakeMacaroon();
setEnabled(false);
} else {
const { deleted } = await platform.revokeMacaroon();
setEnabled(true);
}
setIsLoading(false);
} catch (e) {
setIsLoading(false);
}
};

return (
<dl className='divide-y divide-gray-200 dark:divide-gray-700'>
<Switch.Group as='div' className='py-4 md:grid lg:grid-cols-3 lg:gap-4 lg:py-5'>
<Switch.Label
as='dt'
className='text-sm font-medium text-gray-500 dark:text-gray-400'
passive
>
<a
href='https://deezy.io/'
target='_blank'
className='hover:text-green-500 flex items-center justify-start'
>
Deezy.io <ExternalLinkIcon className='h-3 w-3 ml-1' />
</a>
</Switch.Label>
<dd className='mt-1 flex text-sm text-gray-900 dark:text-gray-300 sm:col-span-2 sm:mt-0'>
<Switch.Description as='span' className='flex-grow'>
<span className='flex-grow'>Automatic Channel Management</span>
</Switch.Description>
<span className='ml-4 flex-shrink-0'>
<Switch
checked={enabled}
onChange={toggleDeezy}
className={classNames(
enabled ? 'bg-green-600' : 'bg-gray-200',
'relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2'
)}
>
<span
className={classNames(
enabled ? 'translate-x-5' : 'translate-x-0',
'pointer-events-none relative inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out'
)}
>
<span
className={classNames(
enabled
? 'opacity-0 ease-out duration-100'
: 'opacity-100 ease-in duration-200',
'absolute inset-0 flex h-full w-full items-center justify-center transition-opacity'
)}
aria-hidden='true'
>
{isLoading ? (
<img className='h-3 w-3' src={FlowerLoading} />
) : (
<svg className='h-3 w-3 text-gray-400' fill='none' viewBox='0 0 12 12'>
<path
d='M4 8l2-2m0 0l2-2M6 6L4 4m2 2l2 2'
stroke='currentColor'
strokeWidth={2}
strokeLinecap='round'
strokeLinejoin='round'
/>
</svg>
)}
</span>
<span
className={classNames(
enabled
? 'opacity-100 ease-in duration-200'
: 'opacity-0 ease-out duration-100',
'absolute inset-0 flex h-full w-full items-center justify-center transition-opacity'
)}
aria-hidden='true'
>
{isLoading ? (
<img className='h-3 w-3' src={FlowerLoading} />
) : (
<svg className='h-3 w-3 text-green-600' fill='currentColor' viewBox='0 0 12 12'>
<path d='M3.707 5.293a1 1 0 00-1.414 1.414l1.414-1.414zM5 8l-.707.707a1 1 0 001.414 0L5 8zm4.707-3.293a1 1 0 00-1.414-1.414l1.414 1.414zm-7.414 2l2 2 1.414-1.414-2-2-1.414 1.414zm3.414 2l4-4-1.414-1.414-4 4 1.414 1.414z' />
</svg>
)}
</span>
</span>
</Switch>
</span>
</dd>
</Switch.Group>
</dl>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import moment from 'moment';

import { Modal, SettingsTable } from 'src/components';

import DeleteAccountModal from './DeleteAccountModal';
import EditAccountNameModal from './EditAccountNameModal';
import DeleteAccountModal from '../DeleteAccountModal';
import EditAccountNameModal from '../EditAccountNameModal';

import { AccountMapContext, ConfigContext } from 'src/context';
import DeezyToggle from './DeezyToggle';

import { AccountMapContext, ConfigContext, PlatformContext } from 'src/context';

import { red500 } from 'src/utils/colors';

Expand All @@ -29,10 +31,12 @@ const GeneralView = () => {
return (
<SettingsTable.Wrapper>
<SettingsTable.HeaderSection>
<SettingsTable.HeaderTitle>Account Information</SettingsTable.HeaderTitle>
<SettingsTable.HeaderSubtitle>
<h3 className='text-lg font-medium leading-6 text-gray-900 dark:text-gray-200'>
Account Information
</h3>
<p className='max-w-2xl text-sm text-gray-500 dark:text-gray-400'>
This information is private and only seen by you.
</SettingsTable.HeaderSubtitle>
</p>
</SettingsTable.HeaderSection>

<SettingsTable.Row>
Expand Down Expand Up @@ -66,10 +70,12 @@ const GeneralView = () => {
</SettingsTable.Row>

<SettingsTable.HeaderSection>
<SettingsTable.HeaderTitle>Connection Information</SettingsTable.HeaderTitle>
<SettingsTable.HeaderSubtitle>
<h3 className='text-lg font-medium leading-6 text-gray-900 dark:text-gray-200'>
Connection Information
</h3>
<p className='max-w-2xl text-sm text-gray-500 dark:text-gray-400'>
Information about the lightning node
</SettingsTable.HeaderSubtitle>
</p>
</SettingsTable.HeaderSection>
<SettingsTable.Row>
<SettingsTable.KeyColumn>Status</SettingsTable.KeyColumn>
Expand All @@ -85,11 +91,27 @@ const GeneralView = () => {
</SettingsTable.ValueColumn>
</SettingsTable.Row>

<div className='mt-10 divide-y divide-gray-200 dark:divide-gray-700'>
<div className='space-y-1'>
<h3 className='text-lg font-medium leading-6 text-gray-900 dark:text-gray-200'>
Integrations
</h3>
<p className='max-w-2xl text-sm text-gray-500 dark:text-gray-400'>
Manage 3rd party integrations and features for your lightning node.
</p>
</div>
<div className='mt-6'>
<DeezyToggle />
</div>
</div>

<SettingsTable.HeaderSection>
<SettingsTable.HeaderTitle>Danger Zone</SettingsTable.HeaderTitle>
<SettingsTable.HeaderSubtitle>
<h3 className='text-lg font-medium leading-6 text-gray-900 dark:text-gray-200'>
Danger Zone
</h3>
<p className='max-w-2xl text-sm text-gray-500 dark:text-gray-400'>
Remove this account from Lily Wallet.
</SettingsTable.HeaderSubtitle>
</p>
</SettingsTable.HeaderSection>
<SettingsTable.Row>
<SettingsTable.KeyColumn>Delete Account</SettingsTable.KeyColumn>
Expand Down
Loading