@lightsparkdev/lightspark-sdk 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/.fossa.yml +6 -0
  2. package/.prettierrc +1 -0
  3. package/.turbo/turbo-build.log +19 -0
  4. package/.turbo/turbo-lint.log +3 -0
  5. package/CHANGELOG.md +49 -0
  6. package/LICENSE +201 -0
  7. package/README.md +137 -0
  8. package/dist/Withdrawal-17e1c8af.d.ts +1672 -0
  9. package/dist/Withdrawal-27a4d10d.d.ts +1672 -0
  10. package/dist/chunk-3VRI7CHE.js +5508 -0
  11. package/dist/chunk-AGEUDR2V.js +4498 -0
  12. package/dist/chunk-N27QHRE4.js +5508 -0
  13. package/dist/client-3bba3f64.d.ts +1302 -0
  14. package/dist/index.cjs +6633 -0
  15. package/dist/index.d.ts +15 -0
  16. package/dist/index.js +1177 -0
  17. package/dist/objects/index.cjs +5347 -0
  18. package/dist/objects/index.d.ts +3 -0
  19. package/dist/objects/index.js +88 -0
  20. package/examples/node-scripts/authHelpers.ts +20 -0
  21. package/examples/node-scripts/createInvoice.ts +64 -0
  22. package/examples/node-scripts/example.ts +288 -0
  23. package/examples/node-scripts/getAccountDashboard.ts +24 -0
  24. package/examples/node-scripts/getNodeChannels.ts +34 -0
  25. package/examples/node-scripts/internalAuthHelpers.ts +26 -0
  26. package/examples/node-scripts/internal_example.ts +296 -0
  27. package/examples/node-scripts/package-lock.json +887 -0
  28. package/examples/node-scripts/package.json +22 -0
  29. package/examples/node-scripts/prettyPrintJsonForDocs.ts +62 -0
  30. package/examples/node-scripts/tsconfig.json +27 -0
  31. package/examples/oauth-example/README.md +19 -0
  32. package/examples/oauth-example/package-lock.json +16071 -0
  33. package/examples/oauth-example/package.json +50 -0
  34. package/examples/oauth-example/public/favicon.ico +0 -0
  35. package/examples/oauth-example/public/index.html +43 -0
  36. package/examples/oauth-example/public/logo192.png +0 -0
  37. package/examples/oauth-example/public/logo512.png +0 -0
  38. package/examples/oauth-example/public/manifest.json +25 -0
  39. package/examples/oauth-example/public/robots.txt +3 -0
  40. package/examples/oauth-example/src/App.css +7 -0
  41. package/examples/oauth-example/src/App.test.tsx +12 -0
  42. package/examples/oauth-example/src/App.tsx +16 -0
  43. package/examples/oauth-example/src/auth/AuthContext.ts +8 -0
  44. package/examples/oauth-example/src/auth/AuthProvider.tsx +44 -0
  45. package/examples/oauth-example/src/auth/RequireAuth.tsx +19 -0
  46. package/examples/oauth-example/src/auth/oauthProvider.ts +35 -0
  47. package/examples/oauth-example/src/components/Button.tsx +39 -0
  48. package/examples/oauth-example/src/components/CurrencyAmount.tsx +117 -0
  49. package/examples/oauth-example/src/components/Dashboard.tsx +158 -0
  50. package/examples/oauth-example/src/components/Table.tsx +22 -0
  51. package/examples/oauth-example/src/hooks/useAccountInfo.tsx +31 -0
  52. package/examples/oauth-example/src/icons/BitcoinB.tsx +20 -0
  53. package/examples/oauth-example/src/icons/Icon.tsx +121 -0
  54. package/examples/oauth-example/src/icons/Satoshi.tsx +28 -0
  55. package/examples/oauth-example/src/index.css +13 -0
  56. package/examples/oauth-example/src/index.tsx +23 -0
  57. package/examples/oauth-example/src/lightsparkclient/LightsparkClientContext.ts +10 -0
  58. package/examples/oauth-example/src/lightsparkclient/LightsparkClientProvider.tsx +53 -0
  59. package/examples/oauth-example/src/logo.svg +1 -0
  60. package/examples/oauth-example/src/pages/DashboardPage.tsx +71 -0
  61. package/examples/oauth-example/src/pages/LoginPage.tsx +63 -0
  62. package/examples/oauth-example/src/react-app-env.d.ts +1 -0
  63. package/examples/oauth-example/src/reportWebVitals.ts +15 -0
  64. package/examples/oauth-example/src/routes/index.tsx +15 -0
  65. package/examples/oauth-example/src/setupTests.ts +5 -0
  66. package/examples/oauth-example/src/utils/currency.ts +483 -0
  67. package/examples/oauth-example/tsconfig.json +20 -0
  68. package/examples/streaming-wallet-extension/.fossa.yml +6 -0
  69. package/examples/streaming-wallet-extension/README.md +17 -0
  70. package/examples/streaming-wallet-extension/craco.config.js +58 -0
  71. package/examples/streaming-wallet-extension/package-lock.json +18260 -0
  72. package/examples/streaming-wallet-extension/package.json +77 -0
  73. package/examples/streaming-wallet-extension/public/index.html +24 -0
  74. package/examples/streaming-wallet-extension/public/lightspark_full.png +0 -0
  75. package/examples/streaming-wallet-extension/public/lightspark_icon_circle.png +0 -0
  76. package/examples/streaming-wallet-extension/public/manifest.json +43 -0
  77. package/examples/streaming-wallet-extension/public/robots.txt +3 -0
  78. package/examples/streaming-wallet-extension/src/App.css +53 -0
  79. package/examples/streaming-wallet-extension/src/App.tsx +425 -0
  80. package/examples/streaming-wallet-extension/src/auth/AccountStorage.ts +28 -0
  81. package/examples/streaming-wallet-extension/src/auth/DemoAccountProvider.ts +99 -0
  82. package/examples/streaming-wallet-extension/src/auth/StreamingDemoCredentials.ts +10 -0
  83. package/examples/streaming-wallet-extension/src/background/PaymentStrategy.ts +36 -0
  84. package/examples/streaming-wallet-extension/src/background/PlaybackRange.ts +31 -0
  85. package/examples/streaming-wallet-extension/src/background/StreamingInvoiceHolder.ts +33 -0
  86. package/examples/streaming-wallet-extension/src/background/TransactionObserver.ts +66 -0
  87. package/examples/streaming-wallet-extension/src/background/VideoPlaybackRanges.ts +38 -0
  88. package/examples/streaming-wallet-extension/src/background/VideoProgressCache.ts +87 -0
  89. package/examples/streaming-wallet-extension/src/background/background.ts +145 -0
  90. package/examples/streaming-wallet-extension/src/background/messageHandling.ts +185 -0
  91. package/examples/streaming-wallet-extension/src/common/datetimes.ts +28 -0
  92. package/examples/streaming-wallet-extension/src/common/settings.ts +12 -0
  93. package/examples/streaming-wallet-extension/src/common/storage.ts +8 -0
  94. package/examples/streaming-wallet-extension/src/common/streamingTabs.ts +27 -0
  95. package/examples/streaming-wallet-extension/src/common/types.tsx +23 -0
  96. package/examples/streaming-wallet-extension/src/components/CirclePlusIcon.tsx +19 -0
  97. package/examples/streaming-wallet-extension/src/components/CurrencyAmount.tsx +110 -0
  98. package/examples/streaming-wallet-extension/src/components/CurrencyAmountRaw.tsx +195 -0
  99. package/examples/streaming-wallet-extension/src/components/LeftArrow.tsx +21 -0
  100. package/examples/streaming-wallet-extension/src/components/Loading.tsx +151 -0
  101. package/examples/streaming-wallet-extension/src/components/StreamingTransactionChip.tsx +95 -0
  102. package/examples/streaming-wallet-extension/src/components/TransactionRow.tsx +93 -0
  103. package/examples/streaming-wallet-extension/src/contentscript/content.ts +123 -0
  104. package/examples/streaming-wallet-extension/src/contentscript/lightsparkDemoDom.tsx +113 -0
  105. package/examples/streaming-wallet-extension/src/contentscript/videoElementParsers.ts +92 -0
  106. package/examples/streaming-wallet-extension/src/index.css +16 -0
  107. package/examples/streaming-wallet-extension/src/index.tsx +11 -0
  108. package/examples/streaming-wallet-extension/src/lightsparkClientProvider.tsx +26 -0
  109. package/examples/streaming-wallet-extension/src/react-app-env.d.ts +1 -0
  110. package/examples/streaming-wallet-extension/src/types/Messages.ts +17 -0
  111. package/examples/streaming-wallet-extension/tsconfig.json +20 -0
  112. package/package.json +87 -0
  113. package/src/auth/AccountTokenAuthProvider.ts +37 -0
  114. package/src/auth/index.ts +3 -0
  115. package/src/client.ts +759 -0
  116. package/src/graphql/BitcoinFeeEstimate.ts +13 -0
  117. package/src/graphql/CreateApiToken.ts +22 -0
  118. package/src/graphql/CreateInvoice.ts +18 -0
  119. package/src/graphql/CreateNodeWalletAddress.ts +13 -0
  120. package/src/graphql/CurrentAccount.ts +13 -0
  121. package/src/graphql/DecodeInvoice.ts +16 -0
  122. package/src/graphql/DeleteApiToken.ts +13 -0
  123. package/src/graphql/FundNode.ts +18 -0
  124. package/src/graphql/LightningFeeEstimateForInvoice.ts +21 -0
  125. package/src/graphql/LightningFeeEstimateForNode.ts +21 -0
  126. package/src/graphql/MultiNodeDashboard.ts +118 -0
  127. package/src/graphql/PayInvoice.ts +29 -0
  128. package/src/graphql/RecoverNodeSigningKey.ts +15 -0
  129. package/src/graphql/RequestWithdrawal.ts +25 -0
  130. package/src/graphql/SendPayment.ts +29 -0
  131. package/src/graphql/SingleNodeDashboard.ts +116 -0
  132. package/src/graphql/TransactionSubscription.ts +16 -0
  133. package/src/graphql/TransactionsForNode.ts +42 -0
  134. package/src/index.ts +5 -0
  135. package/src/objects/Account.ts +1222 -0
  136. package/src/objects/AccountToApiTokensConnection.ts +50 -0
  137. package/src/objects/AccountToChannelsConnection.ts +35 -0
  138. package/src/objects/AccountToNodesConnection.ts +62 -0
  139. package/src/objects/AccountToPaymentRequestsConnection.ts +50 -0
  140. package/src/objects/AccountToTransactionsConnection.ts +112 -0
  141. package/src/objects/ApiToken.ts +80 -0
  142. package/src/objects/BitcoinNetwork.ts +19 -0
  143. package/src/objects/BlockchainBalance.ts +102 -0
  144. package/src/objects/Channel.ts +283 -0
  145. package/src/objects/ChannelClosingTransaction.ts +150 -0
  146. package/src/objects/ChannelFees.ts +34 -0
  147. package/src/objects/ChannelOpeningTransaction.ts +150 -0
  148. package/src/objects/ChannelStatus.ts +25 -0
  149. package/src/objects/ChannelToTransactionsConnection.ts +86 -0
  150. package/src/objects/CreateApiTokenInput.ts +22 -0
  151. package/src/objects/CreateApiTokenOutput.ts +41 -0
  152. package/src/objects/CreateInvoiceInput.ts +27 -0
  153. package/src/objects/CreateInvoiceOutput.ts +21 -0
  154. package/src/objects/CreateNodeWalletAddressInput.ts +15 -0
  155. package/src/objects/CreateNodeWalletAddressOutput.ts +27 -0
  156. package/src/objects/CurrencyAmount.ts +55 -0
  157. package/src/objects/CurrencyUnit.ts +25 -0
  158. package/src/objects/DeleteApiTokenInput.ts +13 -0
  159. package/src/objects/DeleteApiTokenOutput.ts +23 -0
  160. package/src/objects/Deposit.ts +144 -0
  161. package/src/objects/Entity.ts +868 -0
  162. package/src/objects/FeeEstimate.ts +39 -0
  163. package/src/objects/FundNodeInput.ts +16 -0
  164. package/src/objects/FundNodeOutput.ts +28 -0
  165. package/src/objects/GraphNode.ts +110 -0
  166. package/src/objects/Hop.ts +108 -0
  167. package/src/objects/HtlcAttemptFailureCode.ts +65 -0
  168. package/src/objects/IncomingPayment.ts +141 -0
  169. package/src/objects/IncomingPaymentAttempt.ts +96 -0
  170. package/src/objects/IncomingPaymentAttemptStatus.ts +20 -0
  171. package/src/objects/IncomingPaymentToAttemptsConnection.ts +39 -0
  172. package/src/objects/Invoice.ts +226 -0
  173. package/src/objects/InvoiceData.ts +185 -0
  174. package/src/objects/InvoiceType.ts +15 -0
  175. package/src/objects/LightningFeeEstimateForInvoiceInput.ts +28 -0
  176. package/src/objects/LightningFeeEstimateForNodeInput.ts +25 -0
  177. package/src/objects/LightningFeeEstimateOutput.ts +33 -0
  178. package/src/objects/LightningTransaction.ts +393 -0
  179. package/src/objects/LightsparkNode.ts +377 -0
  180. package/src/objects/LightsparkNodePurpose.ts +17 -0
  181. package/src/objects/LightsparkNodeStatus.ts +29 -0
  182. package/src/objects/LightsparkNodeToChannelsConnection.ts +50 -0
  183. package/src/objects/Node.ts +273 -0
  184. package/src/objects/NodeAddress.ts +29 -0
  185. package/src/objects/NodeAddressType.ts +18 -0
  186. package/src/objects/NodeToAddressesConnection.ts +39 -0
  187. package/src/objects/OnChainTransaction.ts +318 -0
  188. package/src/objects/OutgoingPayment.ts +319 -0
  189. package/src/objects/OutgoingPaymentAttempt.ts +164 -0
  190. package/src/objects/OutgoingPaymentAttemptStatus.ts +18 -0
  191. package/src/objects/OutgoingPaymentAttemptToHopsConnection.ts +37 -0
  192. package/src/objects/OutgoingPaymentToAttemptsConnection.ts +39 -0
  193. package/src/objects/PageInfo.ts +31 -0
  194. package/src/objects/PayInvoiceInput.ts +33 -0
  195. package/src/objects/PayInvoiceOutput.ts +22 -0
  196. package/src/objects/PaymentFailureReason.ts +29 -0
  197. package/src/objects/PaymentRequest.ts +231 -0
  198. package/src/objects/PaymentRequestData.ts +183 -0
  199. package/src/objects/PaymentRequestStatus.ts +15 -0
  200. package/src/objects/Permission.ts +39 -0
  201. package/src/objects/RequestWithdrawalInput.ts +35 -0
  202. package/src/objects/RequestWithdrawalOutput.ts +24 -0
  203. package/src/objects/RichText.ts +19 -0
  204. package/src/objects/RoutingTransaction.ts +150 -0
  205. package/src/objects/RoutingTransactionFailureReason.ts +17 -0
  206. package/src/objects/Secret.ts +23 -0
  207. package/src/objects/SendPaymentInput.ts +30 -0
  208. package/src/objects/SendPaymentOutput.ts +22 -0
  209. package/src/objects/Transaction.ts +609 -0
  210. package/src/objects/TransactionFailures.ts +23 -0
  211. package/src/objects/TransactionStatus.ts +23 -0
  212. package/src/objects/TransactionType.ts +31 -0
  213. package/src/objects/TransactionUpdate.ts +67 -0
  214. package/src/objects/WalletDashboard.ts +32 -0
  215. package/src/objects/WebhookEventType.ts +15 -0
  216. package/src/objects/Withdrawal.ts +144 -0
  217. package/src/objects/WithdrawalMode.ts +15 -0
  218. package/src/objects/WithdrawalRequest.ts +224 -0
  219. package/src/objects/WithdrawalRequestStatus.ts +17 -0
  220. package/src/objects/WithdrawalRequestToChannelClosingTransactionsConnection.ts +57 -0
  221. package/src/objects/WithdrawalRequestToChannelOpeningTransactionsConnection.ts +57 -0
  222. package/src/objects/index.ts +108 -0
  223. package/tsconfig.json +5 -0
@@ -0,0 +1,185 @@
1
+ import {
2
+ BitcoinNetwork,
3
+ CurrencyUnit,
4
+ LightsparkClient,
5
+ } from "@lightsparkdev/lightspark-sdk";
6
+ import AccountStorage from "../auth/AccountStorage";
7
+ import { VideoPlaybackUpdateMessage } from "../types/Messages";
8
+ import { LinearPaymentStrategy } from "./PaymentStrategy";
9
+ import StreamingInvoiceHolder from "./StreamingInvoiceHolder";
10
+ import TransactionObserver from "./TransactionObserver";
11
+ import VideoProgressCache from "./VideoProgressCache";
12
+
13
+ const paymentStrategy = new LinearPaymentStrategy(10_000, 1);
14
+
15
+ const playbackMessageReceived = async (
16
+ message: VideoPlaybackUpdateMessage,
17
+ lightsparkClient: LightsparkClient,
18
+ viewerNodeId: string | undefined,
19
+ progressCache: VideoProgressCache,
20
+ invoiceHolder: StreamingInvoiceHolder,
21
+ sendResponse: (response?: any) => void
22
+ ) => {
23
+ const previousRanges = progressCache.getPlayedRanges(message.videoID).slice();
24
+ progressCache.addProgress(
25
+ message.videoID,
26
+ message.prevProgress || 0,
27
+ message.progress
28
+ );
29
+ // Only send payments for the demo streaming video for now:
30
+ if (message.videoID !== "ls_demo") {
31
+ sendResponse({ amountToPay: 0 });
32
+ return;
33
+ }
34
+ const amountToPay = paymentStrategy.onPlayedRange(
35
+ previousRanges,
36
+ progressCache.getPlayedRanges(message.videoID)
37
+ );
38
+ const invoiceToPay = await invoiceHolder.getInvoiceData();
39
+ if (amountToPay > 0) {
40
+ console.log(`Paying: ${amountToPay / 1000} sats`);
41
+ if (!invoiceToPay || !viewerNodeId) {
42
+ console.error("No invoice to pay while streaming");
43
+ } else {
44
+ await lightsparkClient.payInvoice(
45
+ viewerNodeId,
46
+ invoiceToPay,
47
+ Math.ceil(amountToPay * 0.0016 + 5),
48
+ 60,
49
+ amountToPay
50
+ );
51
+ }
52
+ }
53
+ sendResponse({ amountToPay });
54
+ };
55
+
56
+ const getWalletStatus = async (lightsparkClient: LightsparkClient) => {
57
+ const isAuthorized = await lightsparkClient.isAuthorized();
58
+ if (!isAuthorized) {
59
+ return "no_wallet";
60
+ }
61
+ return "funded";
62
+ };
63
+
64
+ let pendingPause: NodeJS.Timeout | undefined;
65
+
66
+ export const onMessageReceived = (
67
+ message: any,
68
+ lightsparkClient: LightsparkClient,
69
+ progressCache: VideoProgressCache,
70
+ invoiceHolder: StreamingInvoiceHolder,
71
+ accountStorage: AccountStorage,
72
+ transactionObserver: TransactionObserver,
73
+ sendResponse: (response: any) => void
74
+ ) => {
75
+ switch (message.id) {
76
+ case "video_play":
77
+ accountStorage.getAccountCredentials().then((account) => {
78
+ transactionObserver.startListening(account!.viewerWalletId);
79
+ if (pendingPause) {
80
+ clearTimeout(pendingPause);
81
+ pendingPause = undefined;
82
+ }
83
+ sendResponse({ status: "ok" });
84
+ });
85
+ break;
86
+ case "video_pause":
87
+ pendingPause = setTimeout(() => {
88
+ transactionObserver.stopListening();
89
+ pendingPause = undefined;
90
+ }, 10000);
91
+ sendResponse({ status: "ok" });
92
+ break;
93
+ case "ping":
94
+ sendResponse("pong");
95
+ break;
96
+ case "get_version":
97
+ sendResponse({ version: chrome.runtime.getManifest().version });
98
+ break;
99
+ case "video_progress":
100
+ accountStorage.getAccountCredentials().then((account) => {
101
+ playbackMessageReceived(
102
+ message,
103
+ lightsparkClient,
104
+ account?.viewerWalletId,
105
+ progressCache,
106
+ invoiceHolder,
107
+ sendResponse
108
+ );
109
+ });
110
+ break;
111
+ case "get_wallet_status":
112
+ // TODO: Send messages when the status changes.
113
+ getWalletStatus(lightsparkClient).then((status) => {
114
+ sendResponse({ status });
115
+ });
116
+ break;
117
+ case "get_wallet_transactions":
118
+ accountStorage.getAccountCredentials().then((account) => {
119
+ if (!account) {
120
+ sendResponse({ transactions: [] });
121
+ return;
122
+ }
123
+
124
+ lightsparkClient
125
+ .getRecentTransactions(
126
+ account.viewerWalletId,
127
+ 20,
128
+ BitcoinNetwork.REGTEST,
129
+ account.allocationTime
130
+ )
131
+ .then((transactions) => {
132
+ sendResponse({ transactions });
133
+ });
134
+ });
135
+ break;
136
+ case "get_streaming_wallet_balances":
137
+ // Hack for testing. Remove this line when releasing:
138
+ progressCache.clear();
139
+ lightsparkClient
140
+ .getAccountDashboard(undefined, BitcoinNetwork.REGTEST)
141
+ .then(async (dashboard) => {
142
+ const zeroSats = { unit: CurrencyUnit.SATOSHI, value: 0 };
143
+ const account = await accountStorage.getAccountCredentials();
144
+ if (!account) {
145
+ sendResponse({
146
+ balances: { viewerBalance: zeroSats, creatorBalance: zeroSats },
147
+ });
148
+ return;
149
+ }
150
+ const viewerNode = dashboard.nodes?.find((node) =>
151
+ node.id.includes(account.viewerWalletId)
152
+ );
153
+ const creatorNode = dashboard.nodes?.find((node) =>
154
+ node.id.includes(account.creatorWalletId)
155
+ );
156
+ const balances = {
157
+ viewerBalance: viewerNode?.localBalance || zeroSats,
158
+ creatorBalance: creatorNode?.localBalance || zeroSats,
159
+ };
160
+ sendResponse({ balances });
161
+ });
162
+ break;
163
+ case "open_and_create_wallet":
164
+ chrome.windows.getCurrent().then((activeWindow) => {
165
+ chrome.windows.create(
166
+ {
167
+ url: "index.html",
168
+ type: "popup",
169
+ width: 300,
170
+ height: 408,
171
+ left: Math.round(
172
+ (activeWindow.left ?? 0) + (activeWindow.width ?? 0) - 480
173
+ ),
174
+ top: Math.round((activeWindow.top ?? 0) + 90),
175
+ },
176
+ () => console.log("opened popup")
177
+ );
178
+ });
179
+ sendResponse({ status: "ok" });
180
+ break;
181
+ default:
182
+ console.log(`Unknown message received: ${JSON.stringify(message)}`);
183
+ sendResponse({ status: "unknown" });
184
+ }
185
+ };
@@ -0,0 +1,28 @@
1
+ import day from "dayjs";
2
+ import utc from "dayjs/plugin/utc";
3
+ import { Maybe } from "./types";
4
+
5
+ const NOT_APPLICABLE = "-";
6
+
7
+ day.extend(utc);
8
+
9
+ export const formatDateTime = (
10
+ datetime: string,
11
+ format: string,
12
+ toUserTime: boolean = true
13
+ ): string => {
14
+ let time_val = day(datetime).utc();
15
+ if (toUserTime) {
16
+ time_val = day(time_val).local();
17
+ }
18
+ return time_val.format(format);
19
+ };
20
+
21
+ export const getFormattedDateTimeOrDefault = (
22
+ datetime: Maybe<string>,
23
+ format: string
24
+ ): string => {
25
+ return datetime === undefined || datetime === null || datetime === ""
26
+ ? NOT_APPLICABLE
27
+ : formatDateTime(datetime, format);
28
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Enable YouTube and Twitch streaming tracking.
3
+ *
4
+ * If you enable this, you will need to add the following to your manifest.json in content_scripts -> matches:
5
+ * [
6
+ * "https://youtube.com/*",
7
+ * "https://www.youtube.com/*",
8
+ * "https://www.twitch.tv/*",
9
+ * "https://twitch.tv/*",
10
+ * ]
11
+ */
12
+ export const ENABLE_YOUTUBE_AND_TWITCH = false;
@@ -0,0 +1,8 @@
1
+ export const INSTANCE_ID_KEY = "instanceID";
2
+
3
+ export const clearStorageKeepingInstanceId = async () => {
4
+ const instanceId = (await chrome.storage.local.get(INSTANCE_ID_KEY))
5
+ ?.instanceID;
6
+ await chrome.storage.local.clear();
7
+ await chrome.storage.local.set({ [INSTANCE_ID_KEY]: instanceId });
8
+ };
@@ -0,0 +1,27 @@
1
+ const URLS = [
2
+ "https://localhost:3000/demos/streaming",
3
+ "http://192.168.86.248:3000/demos/streaming",
4
+ "https://dev.dev.sparkinfra.net/demos/streaming",
5
+ "https://app.lightspark.com/demos/streaming",
6
+ ];
7
+
8
+ export const findActiveStreamingDemoTabs = () => {
9
+ const allAndActive = Promise.all([
10
+ new Promise<chrome.tabs.Tab[]>((resolve) => {
11
+ chrome.tabs.query({ url: URLS }, (tabs) => resolve(tabs));
12
+ }),
13
+ new Promise<chrome.tabs.Tab[]>((resolve) => {
14
+ chrome.tabs.query(
15
+ { url: URLS, active: true, lastFocusedWindow: true },
16
+ (tabs) => resolve(tabs)
17
+ );
18
+ }),
19
+ ]);
20
+ return allAndActive.then(([all, active]) => {
21
+ if (active.length > 0) {
22
+ return active;
23
+ }
24
+ // Reverse the order so that the most recently opened tab is returned.
25
+ return all.reverse();
26
+ });
27
+ };
@@ -0,0 +1,23 @@
1
+ // Copyright ©, 2022, Lightspark Group, Inc. - All Rights Reserved
2
+
3
+ export type Maybe<T> = T | null | undefined;
4
+
5
+ export type ExpandRecursively<T> = T extends object
6
+ ? T extends infer O
7
+ ? { [K in keyof O]: ExpandRecursively<O[K]> } // eslint-disable-line @typescript-eslint/no-unused-vars
8
+ : never
9
+ : T;
10
+
11
+ export type ById<T> = {
12
+ [id: string]: T;
13
+ };
14
+
15
+ export type OmitTypename<T> = Omit<T, "__typename">;
16
+
17
+ export const isType =
18
+ <T extends string>(typename: T) =>
19
+ <N extends { __typename: string }>(
20
+ node: N | undefined | null
21
+ ): node is Extract<N, { __typename: T }> => {
22
+ return node?.__typename === typename;
23
+ };
@@ -0,0 +1,19 @@
1
+ // Copyright ©, 2022, Lightspark Group, Inc. - All Rights Reserved
2
+
3
+ const CirclePlusIcon = () => (
4
+ <svg
5
+ width="12"
6
+ height="13"
7
+ viewBox="0 0 12 13"
8
+ fill="none"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ >
11
+ <path
12
+ d="M6 3.75V9.25M3.25 6.5H8.75M11.5 6.5C11.5 9.53757 9.03757 12 6 12C2.96243 12 0.5 9.53757 0.5 6.5C0.5 3.46243 2.96243 1 6 1C9.03757 1 11.5 3.46243 11.5 6.5Z"
13
+ stroke="white"
14
+ stroke-linecap="round"
15
+ />
16
+ </svg>
17
+ );
18
+
19
+ export default CirclePlusIcon;
@@ -0,0 +1,110 @@
1
+ // Copyright ©, 2022, Lightspark Group, Inc. - All Rights Reserved
2
+ import {
3
+ CurrencyAmount as CurrencyAmountType,
4
+ CurrencyUnit,
5
+ } from "@lightsparkdev/lightspark-sdk";
6
+ import { Maybe } from "../common/types";
7
+ import CurrencyAmountRaw from "./CurrencyAmountRaw";
8
+
9
+ type Props = {
10
+ amount?: CurrencyAmountType | null;
11
+ displayUnit?: CurrencyUnit;
12
+ shortNumber?: boolean;
13
+ shortUnit?: boolean;
14
+ symbol?: boolean;
15
+ useLocaleString?: boolean;
16
+ maximumSignificantDigits?: number;
17
+ maximumFractionDigits?: number;
18
+ minimumFractionDigits?: number;
19
+ dash?: boolean;
20
+ };
21
+
22
+ const CurrencyAmount = (props: Props) => {
23
+ if (!props.amount) {
24
+ return props.dash ? <>-</> : null;
25
+ }
26
+ const amount = convert(props.amount, props.displayUnit);
27
+ return (
28
+ <CurrencyAmountRaw
29
+ value={amount.preferredCurrencyValueApprox}
30
+ unit={amount.preferredCurrencyUnit}
31
+ shortNumber={props.shortNumber}
32
+ shortUnit={props.shortUnit}
33
+ symbol={props.symbol}
34
+ useLocaleString={props.useLocaleString}
35
+ maximumSignificantDigits={props.maximumSignificantDigits}
36
+ maximumFractionDigits={props.maximumFractionDigits}
37
+ minimumFractionDigits={props.minimumFractionDigits}
38
+ />
39
+ );
40
+ };
41
+
42
+ // TODO(Jeremy): consider moving this to fetch the actual exchange rate.
43
+ const SATS_TO_USD = 0.0268;
44
+ const btc_conversions: Map<CurrencyUnit, Map<CurrencyUnit, number>> = new Map([
45
+ [
46
+ CurrencyUnit.BITCOIN,
47
+ new Map([
48
+ [CurrencyUnit.BITCOIN, 1],
49
+ [CurrencyUnit.SATOSHI, 1e8],
50
+ [CurrencyUnit.MILLISATOSHI, 1e11],
51
+ ]),
52
+ ],
53
+ [
54
+ CurrencyUnit.SATOSHI,
55
+ new Map([
56
+ [CurrencyUnit.BITCOIN, 1e-8],
57
+ [CurrencyUnit.SATOSHI, 1],
58
+ [CurrencyUnit.MILLISATOSHI, 1000],
59
+ ]),
60
+ ],
61
+ [
62
+ CurrencyUnit.MILLISATOSHI,
63
+ new Map([
64
+ [CurrencyUnit.BITCOIN, 1e-11],
65
+ [CurrencyUnit.SATOSHI, 0.001],
66
+ [CurrencyUnit.MILLISATOSHI, 1],
67
+ ]),
68
+ ],
69
+ [
70
+ CurrencyUnit.USD,
71
+ new Map([
72
+ [CurrencyUnit.USD, 1],
73
+ [CurrencyUnit.SATOSHI, SATS_TO_USD],
74
+ [CurrencyUnit.BITCOIN, SATS_TO_USD * 1e8],
75
+ [CurrencyUnit.MILLISATOSHI, SATS_TO_USD / 1000],
76
+ ]),
77
+ ],
78
+ ]);
79
+
80
+ const convert = (
81
+ amount: CurrencyAmountType,
82
+ unit: Maybe<CurrencyUnit>
83
+ ): CurrencyAmountType => {
84
+ if (unit === null || unit === undefined || unit === amount.originalUnit)
85
+ return amount;
86
+ const multiplier = btc_conversions.get(amount.originalUnit)?.get(unit);
87
+ if (!multiplier) {
88
+ throw new ConversionError(
89
+ `Unable to convert from ${amount.originalUnit} to ${unit}`
90
+ );
91
+ }
92
+
93
+ return {
94
+ originalUnit: amount.originalUnit,
95
+ originalValue: amount.originalValue,
96
+ preferredCurrencyUnit: unit,
97
+ preferredCurrencyValueApprox: amount.originalValue * multiplier,
98
+ preferredCurrencyValueRounded: amount.originalValue * multiplier,
99
+ };
100
+ };
101
+
102
+ export class ConversionError {
103
+ message: string;
104
+
105
+ constructor(message: string) {
106
+ this.message = message;
107
+ }
108
+ }
109
+
110
+ export default CurrencyAmount;
@@ -0,0 +1,195 @@
1
+ // Copyright ©, 2022, Lightspark Group, Inc. - All Rights Reserved
2
+ import styled from "@emotion/styled/macro";
3
+ import { CurrencyUnit } from "@lightsparkdev/lightspark-sdk";
4
+ import type { Maybe } from "../common/types";
5
+
6
+ type Props = {
7
+ value: Maybe<number>;
8
+ unit: Maybe<CurrencyUnit>;
9
+ shortUnit?: boolean;
10
+ symbol?: boolean;
11
+ shortNumber?: boolean;
12
+ useLocaleString?: boolean;
13
+ maximumSignificantDigits?: number;
14
+ maximumFractionDigits?: number;
15
+ minimumFractionDigits?: number;
16
+ };
17
+
18
+ const CurrencyAmountRaw = (props: Props) => {
19
+ const symbol = () => {
20
+ switch (props.unit) {
21
+ case CurrencyUnit.SATOSHI:
22
+ return <Satoshi />;
23
+ case CurrencyUnit.USD:
24
+ return "$";
25
+ }
26
+ return "";
27
+ };
28
+
29
+ const text = getAsText(props);
30
+ return (
31
+ <Amount>
32
+ {symbol()}
33
+ {text}
34
+ </Amount>
35
+ );
36
+ };
37
+
38
+ export const getAsText = (props: Props): string => {
39
+ const {
40
+ value,
41
+ unit,
42
+ shortUnit,
43
+ symbol,
44
+ shortNumber,
45
+ useLocaleString,
46
+ maximumSignificantDigits,
47
+ maximumFractionDigits,
48
+ minimumFractionDigits,
49
+ } = props;
50
+
51
+ if (value === undefined || value === null) {
52
+ return "ERROR";
53
+ }
54
+
55
+ let amountValue = value;
56
+ /* Currencies should always be represented in the smallest unit, e.g. cents for USD: */
57
+ if (unit === CurrencyUnit.USD) {
58
+ amountValue = value / 100;
59
+ }
60
+
61
+ let number = amountValue.toString();
62
+ if (shortNumber) {
63
+ const abs_val = Math.abs(amountValue);
64
+ if (abs_val >= 1_000_000_000) {
65
+ const newValue = amountValue / 1_000_000_000;
66
+ number = newValue.toFixed(newValue >= 100 ? 0 : 1) + "B";
67
+ } else if (abs_val >= 1_000_000) {
68
+ const newValue = amountValue / 1_000_000;
69
+ number = newValue.toFixed(newValue >= 100 ? 0 : 1) + "M";
70
+ } else if (abs_val >= 1_000) {
71
+ const newValue = amountValue / 1_000;
72
+ number = (amountValue / 1_000).toFixed(newValue >= 100 ? 0 : 1) + "K";
73
+ } else {
74
+ number = amountValue.toFixed(3);
75
+ }
76
+ } else if (useLocaleString) {
77
+ const options: Intl.NumberFormatOptions = {};
78
+ if (maximumSignificantDigits !== undefined) {
79
+ options.maximumSignificantDigits = maximumSignificantDigits;
80
+ }
81
+ if (maximumFractionDigits !== undefined) {
82
+ options.maximumFractionDigits = maximumFractionDigits;
83
+ }
84
+ if (minimumFractionDigits !== undefined) {
85
+ options.minimumFractionDigits = minimumFractionDigits;
86
+ }
87
+ number = Number(number).toLocaleString(undefined, options);
88
+ }
89
+ if (!unit || symbol) {
90
+ return number;
91
+ }
92
+ if (shortUnit) {
93
+ return number + " " + shorttext(unit);
94
+ }
95
+ const isPlural = amountValue > 1;
96
+ const unitText = isPlural ? plural(unit) : singular(unit);
97
+ return number + " " + unitText;
98
+ };
99
+
100
+ const singular = (unit: CurrencyUnit) => {
101
+ switch (unit) {
102
+ case CurrencyUnit.BITCOIN:
103
+ return "Bitcoin";
104
+ case CurrencyUnit.MILLIBITCOIN:
105
+ return "Millibitcoin";
106
+ case CurrencyUnit.MICROBITCOIN:
107
+ return "Microbitcoin";
108
+ case CurrencyUnit.NANOBITCOIN:
109
+ return "Nanobitcoin";
110
+ case CurrencyUnit.SATOSHI:
111
+ return "Satoshi";
112
+ case CurrencyUnit.MILLISATOSHI:
113
+ return "Millisatoshi";
114
+ }
115
+ return unit;
116
+ };
117
+
118
+ const plural = (unit: CurrencyUnit) => {
119
+ switch (unit) {
120
+ case CurrencyUnit.BITCOIN:
121
+ return "Bitcoins";
122
+ case CurrencyUnit.MILLIBITCOIN:
123
+ return "Millibitcoins";
124
+ case CurrencyUnit.MICROBITCOIN:
125
+ return "Microbitcoins";
126
+ case CurrencyUnit.NANOBITCOIN:
127
+ return "Nanobitcoins";
128
+ case CurrencyUnit.SATOSHI:
129
+ return "Satoshis";
130
+ case CurrencyUnit.MILLISATOSHI:
131
+ return "Millisatoshis";
132
+ }
133
+ return unit;
134
+ };
135
+
136
+ const shorttext = (unit: CurrencyUnit) => {
137
+ switch (unit) {
138
+ case CurrencyUnit.BITCOIN:
139
+ return "BTC";
140
+ case CurrencyUnit.MILLIBITCOIN:
141
+ return "mBTC";
142
+ case CurrencyUnit.MICROBITCOIN:
143
+ return "μBTC";
144
+ case CurrencyUnit.SATOSHI:
145
+ return "sat";
146
+ case CurrencyUnit.MILLISATOSHI:
147
+ return "msat";
148
+ }
149
+ return unit;
150
+ };
151
+
152
+ // This is a squared-off version that is compatible with Montserrat.
153
+ type SatProps = {
154
+ color?: string;
155
+ offset?: number;
156
+ size?: number;
157
+ };
158
+
159
+ const Satoshi = (props: SatProps) => (
160
+ <svg
161
+ width="0.675em"
162
+ height="0.9em"
163
+ style={{ transform: "translate(-0.05em, 0.1em)" }}
164
+ viewBox="0 0 26 40"
165
+ fill="none"
166
+ xmlns="http://www.w3.org/2000/svg"
167
+ >
168
+ <rect y="8.88867" width="25.9994" height="4.44434" fill="currentColor" />
169
+ <rect y="17.7788" width="25.9994" height="4.44434" fill="currentColor" />
170
+ <rect y="26.6685" width="25.9994" height="4.44434" fill="currentColor" />
171
+ <rect
172
+ x="15.4753"
173
+ y="34.6748"
174
+ width="5.32497"
175
+ height="4.95226"
176
+ transform="rotate(90 15.4753 34.6748)"
177
+ fill="currentColor"
178
+ />
179
+ <rect
180
+ x="15.4753"
181
+ width="5.33322"
182
+ height="4.95226"
183
+ transform="rotate(90 15.4753 0)"
184
+ fill="currentColor"
185
+ />
186
+ </svg>
187
+ );
188
+
189
+ const Amount = styled.span`
190
+ color: inherit !important;
191
+ white-space: nowrap;
192
+ font-feature-settings: "tnum" on, "lnum" on;
193
+ `;
194
+
195
+ export default CurrencyAmountRaw;
@@ -0,0 +1,21 @@
1
+ // Copyright ©, 2022, Lightspark Group, Inc. - All Rights Reserved
2
+
3
+ const LeftArrow = () => (
4
+ <svg
5
+ width="16"
6
+ height="16"
7
+ viewBox="0 0 16 16"
8
+ fill="none"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ >
11
+ <path
12
+ d="M12.9837 8.00003L3.01636 8.00003M3.01636 8.00003L7.01636 12.1905M3.01636 8.00003L7.01636 3.80955"
13
+ stroke="#666666"
14
+ stroke-width="1.33333"
15
+ stroke-linecap="round"
16
+ stroke-linejoin="round"
17
+ />
18
+ </svg>
19
+ );
20
+
21
+ export default LeftArrow;