Skip to content

Commit

Permalink
[uma] Remove SDK from private repo (#6780) (#280)
Browse files Browse the repository at this point in the history
* [uma] Remove SDK from private repo (#6780)

GitOrigin-RevId: 232ebc6dbdad88222d5525731c921117a795f748

* feat: add initial typography tokens and typography components

GitOrigin-RevId: 8a517bb99f1d4d9799c6803dad003e1d58a9f10c

* feat: add ArticleBody component to specify spacings in Article-like contexts

GitOrigin-RevId: 191a2458f746e387203a691c474da0bc3954de8b

* CI update lock file for PR

* [remote-signing-server] Handle actual webhook data (#6645)

GitOrigin-RevId: 5426782d6fd6f84f1d1df5868ed1e73aa763b868

* feat: add uma light theme (#6798)

GitOrigin-RevId: bedb3b59faa3d1e5a640e67ed5cc03b4b290b904

---------

Co-authored-by: Corey Martin <[email protected]>
Co-authored-by: Brian Siao Tick Chong <[email protected]>
Co-authored-by: Lightspark Eng <[email protected]>
  • Loading branch information
4 people authored Oct 12, 2023
1 parent b8a3d0e commit b895794
Show file tree
Hide file tree
Showing 34 changed files with 690 additions and 2,052 deletions.
26 changes: 12 additions & 14 deletions apps/examples/remote-signing-server/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,24 @@ describe("Test server routes", () => {
"a64c69f1266bc1dc1322c3f40eba7ba2d536c714774a4fc04f0938609482f5d9",
)
.send(
"7b226576656e745f74797065223a202252454d4f54455f5349474e494e47222c20226576656e745f6964223a20223530353364626438633562303435333439346631633134653031646136396364222c202274696d657374616d70223a2022323032332d30392d31385432333a35303a31352e3335353630332b30303a3030222c2022656e746974795f6964223a20226e6f64655f776974685f7365727665725f7369676e696e673a30313861393633352d333637332d383864662d303030302d383237663233303531623139222c202264617461223a207b227375625f6576656e745f74797065223a202245434448222c2022626974636f696e5f6e6574776f726b223a202252454754455354222c2022706565725f7075626c69635f6b6579223a2022303331373364393764303937336435393637313663386364313430363665323065323766363836366162323134666430346431363033303136313564653738663732227d7d",
`{"event_type": "REMOTE_SIGNING", "event_id": "5053dbd8c5b0453494f1c14e01da69cd", "timestamp": "2023-09-18T23:50:15.355603+00:00", "entity_id": "node_with_server_signing:018a9635-3673-88df-0000-827f23051b19", "data": {"sub_event_type": "ECDH", "bitcoin_network": "REGTEST", "peer_public_key": "03173d97d0973d596716c8cd14066e20e27f6866ab214fd04d160301615de78f72"}}`,
);

expect(response.status).toBe(200);
});

test("error reponse from /lightspark-webhook webhook data is invalid", async () => {
let response: supertest.Response;
try {
jest
.spyOn(LightsparkClient.prototype, "executeRawQuery")
.mockReturnValue(Promise.resolve("mock-query-response"));
response = await request
.post("/lightspark-webhook")
.set(
"lightspark-signature",
"a64c69f1266bc1dc1322c3f40eba7ba2d536c714774a4fc04f0938609482f5d9",
)
.send("7b226576656e");
expect(response.status).toBe(500);
} catch (error) {}
jest
.spyOn(LightsparkClient.prototype, "executeRawQuery")
.mockReturnValue(Promise.resolve("mock-query-response"));
response = await request
.post("/lightspark-webhook")
.set(
"lightspark-signature",
"a64c69f1266bc1dc1322c3f40eba7ba2d536c714774a4fc04f0938609482f5d9",
)
.send("7b226576656e");
expect(response.status).toBe(500);
});
});
80 changes: 45 additions & 35 deletions apps/examples/remote-signing-server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import {
AccountTokenAuthProvider,
LightsparkClient,
RemoteSigningWebhookHandler,
verifyAndParseWebhook,
WebhookEvent,
WebhookEventType,
WEBHOOKS_SIGNATURE_HEADER,
} from "@lightsparkdev/lightspark-sdk";
import {
EnvCredentials,
Expand All @@ -17,61 +20,68 @@ export const app = express();
const WEBHOOK_SECRET = process.env.RK_WEBHOOK_SECRET;
const MASTER_SEED_HEX = process.env.RK_MASTER_SEED_HEX;

app.use(bodyParser.text({ type: "*/*" })); // Middleware to parse raw body
app.use(bodyParser.raw({ type: "*/*" })); // Middleware to parse raw body

app.get("/ping", (req, res) => {
console.log("ping");
res.send("OK");
});

app.post("/lightspark-webhook", (req, res) => {
app.post("/lightspark-webhook", async (req, res) => {
let credentials: EnvCredentials;
try {
try {
credentials = getCredentialsFromEnvOrThrow();
} catch (e) {
res.status(500).send("Unable to get credentials from env");
return;
}

const lightsparkClient = new LightsparkClient(
new AccountTokenAuthProvider(
credentials.apiTokenClientId,
credentials.apiTokenClientSecret,
),
credentials.baseUrl,
);

const validator = {
should_sign: (webhook: WebhookEvent) => true,
};
const remoteSigningHandler = new RemoteSigningWebhookHandler(
lightsparkClient,
hexToBytes(MASTER_SEED_HEX),
validator,
);

const signatureHeader = req.headers["lightspark-signature"];
console.log("signatureHeader", signatureHeader);
const signatureHeader = req.headers[WEBHOOKS_SIGNATURE_HEADER];

if (typeof signatureHeader !== "string") {
console.error("Invalid signature header");
res.status(400).send("Invalid signature header");
return;
}

console.log("body", req.body);

const result = remoteSigningHandler.handleWebhookRequest(
hexToBytes(req.body),
const webhook = await verifyAndParseWebhook(
req.body,
signatureHeader,
WEBHOOK_SECRET,
);
console.log("result", result);

switch (webhook.event_type) {
case WebhookEventType.REMOTE_SIGNING:
try {
credentials = getCredentialsFromEnvOrThrow();
} catch (e) {
res.status(500).send("Unable to get credentials from env");
return;
}

const lightsparkClient = new LightsparkClient(
new AccountTokenAuthProvider(
credentials.apiTokenClientId,
credentials.apiTokenClientSecret,
),
credentials.baseUrl,
);

const validator = {
should_sign: (webhook: WebhookEvent) => true,
};

const remoteSigningHandler = new RemoteSigningWebhookHandler(
lightsparkClient,
hexToBytes(MASTER_SEED_HEX),
validator,
);

const result = remoteSigningHandler.handleWebhookRequest(
req.body,
signatureHeader,
WEBHOOK_SECRET,
);
break;
default:
res.status(400).send("Unknown webhook type");
}

res.send("OK");
} catch (e) {
console.error(e);
res.status(500).send("Internal server error");
}
});
2 changes: 1 addition & 1 deletion packages/ui/components/UnstyledButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { standardFocusOutline } from "@lightsparkdev/ui/styles/common";

export const UnstyledButton = styled.button`
${standardFocusOutline}
font-family: ${({ theme }) => theme.fontFamily};
font-family: ${({ theme }) => theme.typography.fontFamilies.main};
appearance: none;
background: transparent;
border: none;
Expand Down
36 changes: 29 additions & 7 deletions packages/ui/styles/colors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { CSSInterpolation } from "@emotion/css";
import type { Theme } from "@emotion/react";
import { css, useTheme } from "@emotion/react";
import { Breakpoints, useBreakpoints } from "./breakpoints";
import { getTypography } from "./fonts/typographyTokens";

const neutral = {
black: "#000000",
Expand All @@ -23,11 +24,14 @@ const neutral = {
};

const uma = {
background: "#F9F9F9",
black: "#16171A",
blue: "#0068C9",
blue50: "#C0C9D6",
blue80: "#DCE2EA",
blue90: "#EBEEF2",
blue95: "#F2F5F7",
secondary: "#686A72",
stroke: "#C0C9D6",
};

Expand Down Expand Up @@ -80,7 +84,6 @@ interface BaseTheme {
c8Neutral: string;
c9Neutral: string;
danger: string;
fontFamily: string;
hcNeutral: string;
hcNeutralFromBg: (hex: string) => string;
info: string;
Expand All @@ -92,6 +95,7 @@ interface BaseTheme {
primary: string;
success: string;
text: string;
typography: ReturnType<typeof getTypography>;
vlcNeutral: string;
warning: string;
}
Expand All @@ -108,11 +112,11 @@ declare module "@emotion/react" {
export interface Theme extends LightsparkTheme {}
}

function extend(obj: BaseTheme, rest: LightsparkSurfaces) {
function extend(obj: BaseTheme, rest: Partial<LightsparkTheme>) {
return {
...obj,
...rest,
};
} as LightsparkTheme;
}

function extendBase(obj: BaseTheme, rest: Partial<BaseTheme>) {
Expand Down Expand Up @@ -149,7 +153,6 @@ const lightBaseTheme: BaseTheme = {
c8Neutral: neutral.gray20,
c9Neutral: neutral.gray10,
danger: colors.danger,
fontFamily: "Montserrat",
hcNeutral: colors.black,
hcNeutralFromBg: (bgHex) =>
hcNeutralFromBg(bgHex, colors.black, colors.white),
Expand All @@ -162,6 +165,7 @@ const lightBaseTheme: BaseTheme = {
primary: colors.primary,
success: colors.success,
text: colors.black,
typography: getTypography(),
vlcNeutral: neutral.gray95,
warning: colors.warning,
};
Expand All @@ -182,7 +186,6 @@ const darkBaseTheme: BaseTheme = {
c8Neutral: neutral.gray80,
c9Neutral: neutral.gray90,
danger: colors.danger,
fontFamily: "Montserrat",
hcNeutral: colors.white,
hcNeutralFromBg: (bgHex) =>
hcNeutralFromBg(bgHex, colors.white, colors.black),
Expand All @@ -195,6 +198,7 @@ const darkBaseTheme: BaseTheme = {
primary: colors.primary,
success: colors.success,
text: colors.white,
typography: getTypography(),
vlcNeutral: neutral.gray20,
warning: colors.warning,
};
Expand Down Expand Up @@ -228,16 +232,34 @@ const darkTheme = extend(darkBaseTheme, {
}),
});

export const themeWithFont = (theme: Theme, fontFamily: string) => {
return extendBase(theme, { fontFamily });
const umaLightTheme = extend(lightTheme, {
bg: uma.background,
smBg: uma.background,
});

/**
* Allows setting typography in cases where a custom font is needed.
* Setting custom fonts should only be necessary for next fonts.
*/
export const themeWithTypography = (
theme: Theme,
typography: ReturnType<typeof getTypography>,
) => {
return extendBase(theme, { typography });
};

export const themes: {
light: LightsparkTheme;
dark: LightsparkTheme;
uma: {
light: LightsparkTheme;
};
} = {
light: lightTheme,
dark: darkTheme,
uma: {
light: umaLightTheme,
},
};

export const isDark = (theme: Theme) => theme.type === Themes.Dark;
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/styles/fields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const textInputStyle = ({
position: relative;
z-index: ${z.textInput};
font-family: ${theme.fontFamily};
font-family: ${theme.typography?.fontFamilies.main};
padding: ${textInputPaddingPx - (hasError ? 1 : 0)}px;
${paddingLeftPx
? `padding-left: ${paddingLeftPx - (hasError ? 1 : 0)}px;`
Expand Down
29 changes: 29 additions & 0 deletions packages/ui/styles/fonts/typography/Article.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use client";
import styled from "@emotion/styled";
import { StyledBody } from "./Body";
import { headlineSelector } from "./Headline";

export const Article = styled.article`
${headlineSelector("h1")} {
margin: 0;
padding-bottom: 8px;
}
${headlineSelector("h2")}, ${headlineSelector("h3")}}, ${headlineSelector(
"h4",
)}, ${headlineSelector("h5")}, ${headlineSelector("h6")} {
padding-top: 32px;
padding-bottom: 8px;
margin: 0;
}
${StyledBody} {
margin-top: 8px;
margin-bottom: 8px;
}
img {
margin-top: 16px;
margin-bottom: 16px;
}
`;
30 changes: 30 additions & 0 deletions packages/ui/styles/fonts/typography/Body.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use client";

import styled from "@emotion/styled";
import { App, getTypographyString, TokenSize } from "../typographyTokens";

interface Props {
children: React.ReactNode;
app?: App;
size?: TokenSize;
}

export const Body = ({
children,
app = App.Lightspark,
size = TokenSize.Medium,
}: Props) => {
return (
<StyledBody app={app} size={size}>
{children}
</StyledBody>
);
};

export const StyledBody = styled.p<Props>`
${({ theme, app, size }) => {
return app && size
? getTypographyString(theme.typography[app].Body[size])
: "";
}}
`;
30 changes: 30 additions & 0 deletions packages/ui/styles/fonts/typography/Code.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use client";

import styled from "@emotion/styled";
import { App, getTypographyString, TokenSize } from "../typographyTokens";

interface Props {
children: React.ReactNode;
app?: App;
size?: TokenSize;
}

export const Code = ({
children,
app = App.Lightspark,
size = TokenSize.Medium,
}: Props) => {
return (
<CodeStyles app={app} size={size}>
{children}
</CodeStyles>
);
};

const CodeStyles = styled.div<Props>`
${({ theme, app, size }) => {
return app && size
? getTypographyString(theme.typography[app].Code[size])
: "";
}}
`;
Loading

0 comments on commit b895794

Please sign in to comment.