Skip to content

Commit

Permalink
[js] Update to latest schema for 3P packages (#242)
Browse files Browse the repository at this point in the history
* [js] Update to latest schema for 3P packages (#6140)

GitOrigin-RevId: 74d531dd26dbb7a23a7bd8a7ec75c98383dd8709

* [lightspark-sdk] Update schema endpoint to latest

GitOrigin-RevId: 8b6cd6e3fab07c7d0d29d5783fa849e6a3d8bf0a

* [generator] handle nullable lists in js_writer and fix LightsparkNode typenames (#6182)

- updates js_writer to handle nullable lists
- fixes node names due to OSK/remote changes

GitOrigin-RevId: ba076fb3153c2056439c9fed35f170be3bf8f2cd

* Add the uma mutations to JS and update code samples. (#6187)

fyi @coreymartin

GitOrigin-RevId: e1997b4c2e3185dc05d304aff9a8eceed5f4b6a1

* Lint fix

GitOrigin-RevId: 4ac922cb9af037dce2496dee0391175fe319975e

* [lightspark-sdk] add remote signing support in lightspark client (#6089)

- adds enum for signing key types
- adds property to `NodeKeyCache` to save signing key type
- changes `Requester` to add signing data specific to signing key type
- adds wasm packed `lightspark_crypto` lib
- related PR:
lightsparkdev/lightspark-crypto-uniffi#31
- adds `loadNodeSigningKey` function to client which handles both rsa
and secp key types for OSK and remote signing
- updates documentation to reflect new `loadNodeSigningKey` function
- adds `SigningKeyLoader` classes to handle loading logic

Tested using lightspark-cli
lightsparkdev/webdev#6203

GitOrigin-RevId: 07daa2cd7c01610a65f5a809d37c6e69130d5330

* CI update lock file for PR

* [lightspark-cli] add remote signing support (#6203)

- adds option to select node for operations that use a node
- updates wasm packed lightspark_crypto lib
- uses loadNodeSigningKey to unlock/provide credentials for both OSK and
remote signing nodes

Depends on: lightsparkdev/webdev#6089

GitOrigin-RevId: 3881892bcb99c19779fcacac3dadd97959ab75ba

* Fixing the number of concurrent threads for turbo

GitOrigin-RevId: 7ca02542f56c2b15f688e82d6c1bb621d976c0c9

* [core] change SigningKey hashing method depending on environment (#6249)

https://lightsparkgroup.slack.com/archives/C03HYQQ2HT6/p1695228450140589

Ran into issues using createHash in core because it's used in browser
environments as well. Only import "crypto" if in node, and otherwise use
subtle crypto.

---------

Co-authored-by: Corey Martin <[email protected]>
GitOrigin-RevId: 411e19138fc476550a4207759591a34eedf97f5f

* update lock file

* set util to false

* Create shaggy-swans-invent.md

* Create six-camels-tell.md

* format changelog

* Create forty-poets-dance.md

* Create five-geese-roll.md

* Update .changeset/six-camels-tell.md

---------

Co-authored-by: Corey Martin <[email protected]>
Co-authored-by: Brian Siao Tick Chong <[email protected]>
Co-authored-by: Jeremy Klein <[email protected]>
Co-authored-by: Lightspark Eng <[email protected]>
Co-authored-by: Vincent Durmont <[email protected]>
  • Loading branch information
6 people authored Sep 20, 2023
1 parent 79d0c2f commit 1f00a50
Show file tree
Hide file tree
Showing 104 changed files with 7,516 additions and 1,550 deletions.
8 changes: 8 additions & 0 deletions .changeset/five-geese-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@lightsparkdev/lightspark-cli": patch
---

Add remote signing support
- adds option to select node for operations that use a node
- updates wasm packed lightspark_crypto lib
- uses loadNodeSigningKey to unlock/provide credentials for both OSK and remote signing nodes
6 changes: 6 additions & 0 deletions .changeset/forty-poets-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@lightsparkdev/core": major
---

Change SigningKey hashing method depending on environment
BREAKING: NodeKeyCaches loadKey now requires signingKeyType as a parameter
5 changes: 5 additions & 0 deletions .changeset/shaggy-swans-invent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lightsparkdev/wallet-sdk": patch
---

Update to latest 3P API schema
16 changes: 16 additions & 0 deletions .changeset/six-camels-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@lightsparkdev/lightspark-sdk": major
---

Update to latest 3P API schema
Add uma mutations
Add remote signing support

- adds enum for signing key types
- adds property to NodeKeyCache to save signing key type
- changes Requester to add signing data specific to signing key type
- adds wasm packed lightspark_crypto lib
- adds loadNodeSigningKey function to client which handles both rsa and secp key types for OSK and remote signing
- updates documentation to reflect new loadNodeSigningKey function
- updates wasm packed lightspark_crypto lib
- BREAKING: Removes LightsparkClient unlockNode and adds loadNodeSigningKey which should be used for loading signing keys instead
8 changes: 8 additions & 0 deletions apps/examples/streaming-wallet-extension/craco.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ module.exports = {
configure: (webpackConfig, { env, paths }) => {
return {
...webpackConfig,
resolve: {
extensions: [".js", ".jsx", ".ts", ".tsx"],
fallback: {
path: false,
fs: false,
util: false,
},
},
entry: {
main: [
env === "development" &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import styled from "@emotion/styled";
import {
ChannelClosingTransaction,
ChannelOpeningTransaction,
IncomingPayment,
OutgoingPayment,
RoutingTransaction,
Transaction,
Expand Down Expand Up @@ -43,7 +42,7 @@ const getTransactionOtherNode = (transaction: Transaction): Maybe<string> => {
case "OutgoingPayment":
return (transaction as OutgoingPayment).destinationId;
case "IncomingPayment":
return (transaction as IncomingPayment).originId;
return "Unknown";
case "RoutingTransaction":
return (transaction as RoutingTransaction).incomingChannelId;
default:
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"lint": "turbo run lint",
"lint:fix": "turbo run lint:fix",
"release": "turbo build && changeset publish",
"start:check": "turbo run build && turbo run start types:watch lint:watch --parallel --concurrency 60",
"start": "turbo run build && turbo run start --concurrency 60",
"start:check": "turbo run build && turbo run start types:watch lint:watch --parallel --concurrency 64",
"start": "turbo run build && turbo run start --concurrency 64",
"test": "turbo run test",
"types": "turbo run types"
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"dayjs": "^1.11.7",
"graphql": "^16.6.0",
"graphql-ws": "^5.11.3",
"secp256k1": "^5.0.0",
"text-encoding": "^0.7.0",
"ws": "^8.12.1",
"zen-observable-ts": "^1.1.0"
Expand All @@ -76,6 +77,7 @@
"@lightsparkdev/eslint-config": "*",
"@lightsparkdev/tsconfig": "0.0.0",
"@types/crypto-js": "^4.1.1",
"@types/secp256k1": "^4.0.3",
"@types/ws": "^8.5.4",
"eslint": "^8.3.0",
"eslint-watch": "^8.0.0",
Expand Down
55 changes: 45 additions & 10 deletions packages/core/src/crypto/NodeKeyCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ import autoBind from "auto-bind";

import { b64decode } from "../utils/base64.js";
import type { CryptoInterface } from "./crypto.js";
import { DefaultCrypto } from "./crypto.js";
import { DefaultCrypto, LightsparkSigningException } from "./crypto.js";
import type { KeyOrAliasType } from "./KeyOrAlias.js";
import {
RSASigningKey,
Secp256k1SigningKey,
type SigningKey,
} from "./SigningKey.js";
import { SigningKeyType } from "./types.js";

class NodeKeyCache {
private idToKey: Map<string, CryptoKey | string>;
private idToKey: Map<string, SigningKey>;

constructor(private readonly cryptoImpl: CryptoInterface = DefaultCrypto) {
this.idToKey = new Map();
autoBind(this);
Expand All @@ -17,23 +24,51 @@ class NodeKeyCache {
public async loadKey(
id: string,
keyOrAlias: KeyOrAliasType,
): Promise<CryptoKey | string | null> {
signingKeyType: SigningKeyType,
): Promise<SigningKey | null> {
let signingKey: SigningKey;

if (keyOrAlias.alias !== undefined) {
this.idToKey.set(id, keyOrAlias.alias);
return keyOrAlias.alias;
switch (signingKeyType) {
case SigningKeyType.RSASigningKey:
signingKey = new RSASigningKey(
{ alias: keyOrAlias.alias },
this.cryptoImpl,
);
break;
default:
throw new LightsparkSigningException(
`Aliases are not supported for signing key type ${signingKeyType}`,
);
}

this.idToKey.set(id, signingKey);
return signingKey;
}
const decoded = b64decode(this.stripPemTags(keyOrAlias.key));

try {
const key = await this.cryptoImpl.importPrivateSigningKey(decoded);
this.idToKey.set(id, key);
return key;
if (signingKeyType === SigningKeyType.Secp256k1SigningKey) {
signingKey = new Secp256k1SigningKey(keyOrAlias.key);
} else {
const decoded = b64decode(this.stripPemTags(keyOrAlias.key));
const cryptoKeyOrAlias =
await this.cryptoImpl.importPrivateSigningKey(decoded);
const key =
typeof cryptoKeyOrAlias === "string"
? { alias: cryptoKeyOrAlias }
: cryptoKeyOrAlias;
signingKey = new RSASigningKey(key, this.cryptoImpl);
}

this.idToKey.set(id, signingKey);
return signingKey;
} catch (e) {
console.log("Error importing key: ", e);
}
return null;
}

public getKey(id: string): CryptoKey | string | undefined {
public getKey(id: string): SigningKey | undefined {
return this.idToKey.get(id);
}

Expand Down
54 changes: 54 additions & 0 deletions packages/core/src/crypto/SigningKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import secp256k1 from "secp256k1";
import {
createSha256Hash,
hexToBytes,
SigningKeyType,
type CryptoInterface,
} from "../index.js";

interface Alias {
alias: string;
}

function isAlias(key: CryptoKey | Alias): key is Alias {
return "alias" in key;
}

export abstract class SigningKey {
readonly type: SigningKeyType;

constructor(type: SigningKeyType) {
this.type = type;
}

abstract sign(data: Uint8Array): Promise<ArrayBuffer>;
}

export class RSASigningKey extends SigningKey {
constructor(
private readonly privateKey: CryptoKey | Alias,
private readonly cryptoImpl: CryptoInterface,
) {
super(SigningKeyType.RSASigningKey);
}

async sign(data: Uint8Array) {
const key = isAlias(this.privateKey)
? this.privateKey.alias
: this.privateKey;
return this.cryptoImpl.sign(key, data);
}
}

export class Secp256k1SigningKey extends SigningKey {
constructor(private readonly privateKey: string) {
super(SigningKeyType.Secp256k1SigningKey);
}

async sign(data: Uint8Array) {
const keyBytes = new Uint8Array(hexToBytes(this.privateKey));
const hash = await createSha256Hash(data);
const signResult = secp256k1.ecdsaSign(hash, keyBytes);
return signResult.signature;
}
}
2 changes: 2 additions & 0 deletions packages/core/src/crypto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export * from "./crypto.js";
export * from "./KeyOrAlias.js";
export { default as LightsparkSigningException } from "./LightsparkSigningException.js";
export { default as NodeKeyCache } from "./NodeKeyCache.js";
export * from "./SigningKey.js";
export * from "./types.js";
4 changes: 4 additions & 0 deletions packages/core/src/crypto/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum SigningKeyType {
RSASigningKey = "RSASigningKey",
Secp256k1SigningKey = "Secp256k1SigningKey",
}
5 changes: 3 additions & 2 deletions packages/core/src/requester/Requester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,10 @@ class Requester {
const encodedPayload = new TextEncoderImpl().encode(
JSON.stringify(payload),
);
const signedPayload = await this.cryptoImpl.sign(key, encodedPayload);
const encodedSignedPayload = b64encode(signedPayload);

const signedPayload = await key.sign(encodedPayload);

const encodedSignedPayload = b64encode(signedPayload);
headers["X-Lightspark-Signing"] = JSON.stringify({
v: "1",
signature: encodedSignedPayload,
Expand Down
12 changes: 12 additions & 0 deletions packages/core/src/utils/createHash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { isBrowser } from "./environment.js";

export const createSha256Hash = async (
data: Uint8Array,
): Promise<Uint8Array> => {
if (isBrowser) {
return new Uint8Array(await window.crypto.subtle.digest("SHA-256", data));
} else {
const { createHash } = await import("crypto");
return createHash("sha256").update(data).digest();
}
};
15 changes: 15 additions & 0 deletions packages/core/src/utils/hex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const bytesToHex = (bytes: Uint8Array): string => {
return bytes.reduce((acc: string, byte: number) => {
return (acc += ("0" + byte.toString(16)).slice(-2));
}, "");
};

export const hexToBytes = (hex: string): Uint8Array => {
const bytes: number[] = [];

for (let c = 0; c < hex.length; c += 2) {
bytes.push(parseInt(hex.substr(c, 2), 16));
}

return Uint8Array.from(bytes);
};
2 changes: 2 additions & 0 deletions packages/core/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright ©, 2023-present, Lightspark Group, Inc. - All Rights Reserved

export * from "./base64.js";
export * from "./createHash.js";
export * from "./currency.js";
export * from "./environment.js";
export * from "./hex.js";
export * from "./types.js";
2 changes: 1 addition & 1 deletion packages/core/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": "@lightsparkdev/tsconfig/base.json",
"include": ["src"],
"include": ["src", "src/crypto/types.ts"],
"exclude": ["test", "node_modules", "dist"]
}
Loading

0 comments on commit 1f00a50

Please sign in to comment.