@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.
- package/.fossa.yml +6 -0
- package/.prettierrc +1 -0
- package/.turbo/turbo-build.log +19 -0
- package/.turbo/turbo-lint.log +3 -0
- package/CHANGELOG.md +49 -0
- package/LICENSE +201 -0
- package/README.md +137 -0
- package/dist/Withdrawal-17e1c8af.d.ts +1672 -0
- package/dist/Withdrawal-27a4d10d.d.ts +1672 -0
- package/dist/chunk-3VRI7CHE.js +5508 -0
- package/dist/chunk-AGEUDR2V.js +4498 -0
- package/dist/chunk-N27QHRE4.js +5508 -0
- package/dist/client-3bba3f64.d.ts +1302 -0
- package/dist/index.cjs +6633 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +1177 -0
- package/dist/objects/index.cjs +5347 -0
- package/dist/objects/index.d.ts +3 -0
- package/dist/objects/index.js +88 -0
- package/examples/node-scripts/authHelpers.ts +20 -0
- package/examples/node-scripts/createInvoice.ts +64 -0
- package/examples/node-scripts/example.ts +288 -0
- package/examples/node-scripts/getAccountDashboard.ts +24 -0
- package/examples/node-scripts/getNodeChannels.ts +34 -0
- package/examples/node-scripts/internalAuthHelpers.ts +26 -0
- package/examples/node-scripts/internal_example.ts +296 -0
- package/examples/node-scripts/package-lock.json +887 -0
- package/examples/node-scripts/package.json +22 -0
- package/examples/node-scripts/prettyPrintJsonForDocs.ts +62 -0
- package/examples/node-scripts/tsconfig.json +27 -0
- package/examples/oauth-example/README.md +19 -0
- package/examples/oauth-example/package-lock.json +16071 -0
- package/examples/oauth-example/package.json +50 -0
- package/examples/oauth-example/public/favicon.ico +0 -0
- package/examples/oauth-example/public/index.html +43 -0
- package/examples/oauth-example/public/logo192.png +0 -0
- package/examples/oauth-example/public/logo512.png +0 -0
- package/examples/oauth-example/public/manifest.json +25 -0
- package/examples/oauth-example/public/robots.txt +3 -0
- package/examples/oauth-example/src/App.css +7 -0
- package/examples/oauth-example/src/App.test.tsx +12 -0
- package/examples/oauth-example/src/App.tsx +16 -0
- package/examples/oauth-example/src/auth/AuthContext.ts +8 -0
- package/examples/oauth-example/src/auth/AuthProvider.tsx +44 -0
- package/examples/oauth-example/src/auth/RequireAuth.tsx +19 -0
- package/examples/oauth-example/src/auth/oauthProvider.ts +35 -0
- package/examples/oauth-example/src/components/Button.tsx +39 -0
- package/examples/oauth-example/src/components/CurrencyAmount.tsx +117 -0
- package/examples/oauth-example/src/components/Dashboard.tsx +158 -0
- package/examples/oauth-example/src/components/Table.tsx +22 -0
- package/examples/oauth-example/src/hooks/useAccountInfo.tsx +31 -0
- package/examples/oauth-example/src/icons/BitcoinB.tsx +20 -0
- package/examples/oauth-example/src/icons/Icon.tsx +121 -0
- package/examples/oauth-example/src/icons/Satoshi.tsx +28 -0
- package/examples/oauth-example/src/index.css +13 -0
- package/examples/oauth-example/src/index.tsx +23 -0
- package/examples/oauth-example/src/lightsparkclient/LightsparkClientContext.ts +10 -0
- package/examples/oauth-example/src/lightsparkclient/LightsparkClientProvider.tsx +53 -0
- package/examples/oauth-example/src/logo.svg +1 -0
- package/examples/oauth-example/src/pages/DashboardPage.tsx +71 -0
- package/examples/oauth-example/src/pages/LoginPage.tsx +63 -0
- package/examples/oauth-example/src/react-app-env.d.ts +1 -0
- package/examples/oauth-example/src/reportWebVitals.ts +15 -0
- package/examples/oauth-example/src/routes/index.tsx +15 -0
- package/examples/oauth-example/src/setupTests.ts +5 -0
- package/examples/oauth-example/src/utils/currency.ts +483 -0
- package/examples/oauth-example/tsconfig.json +20 -0
- package/examples/streaming-wallet-extension/.fossa.yml +6 -0
- package/examples/streaming-wallet-extension/README.md +17 -0
- package/examples/streaming-wallet-extension/craco.config.js +58 -0
- package/examples/streaming-wallet-extension/package-lock.json +18260 -0
- package/examples/streaming-wallet-extension/package.json +77 -0
- package/examples/streaming-wallet-extension/public/index.html +24 -0
- package/examples/streaming-wallet-extension/public/lightspark_full.png +0 -0
- package/examples/streaming-wallet-extension/public/lightspark_icon_circle.png +0 -0
- package/examples/streaming-wallet-extension/public/manifest.json +43 -0
- package/examples/streaming-wallet-extension/public/robots.txt +3 -0
- package/examples/streaming-wallet-extension/src/App.css +53 -0
- package/examples/streaming-wallet-extension/src/App.tsx +425 -0
- package/examples/streaming-wallet-extension/src/auth/AccountStorage.ts +28 -0
- package/examples/streaming-wallet-extension/src/auth/DemoAccountProvider.ts +99 -0
- package/examples/streaming-wallet-extension/src/auth/StreamingDemoCredentials.ts +10 -0
- package/examples/streaming-wallet-extension/src/background/PaymentStrategy.ts +36 -0
- package/examples/streaming-wallet-extension/src/background/PlaybackRange.ts +31 -0
- package/examples/streaming-wallet-extension/src/background/StreamingInvoiceHolder.ts +33 -0
- package/examples/streaming-wallet-extension/src/background/TransactionObserver.ts +66 -0
- package/examples/streaming-wallet-extension/src/background/VideoPlaybackRanges.ts +38 -0
- package/examples/streaming-wallet-extension/src/background/VideoProgressCache.ts +87 -0
- package/examples/streaming-wallet-extension/src/background/background.ts +145 -0
- package/examples/streaming-wallet-extension/src/background/messageHandling.ts +185 -0
- package/examples/streaming-wallet-extension/src/common/datetimes.ts +28 -0
- package/examples/streaming-wallet-extension/src/common/settings.ts +12 -0
- package/examples/streaming-wallet-extension/src/common/storage.ts +8 -0
- package/examples/streaming-wallet-extension/src/common/streamingTabs.ts +27 -0
- package/examples/streaming-wallet-extension/src/common/types.tsx +23 -0
- package/examples/streaming-wallet-extension/src/components/CirclePlusIcon.tsx +19 -0
- package/examples/streaming-wallet-extension/src/components/CurrencyAmount.tsx +110 -0
- package/examples/streaming-wallet-extension/src/components/CurrencyAmountRaw.tsx +195 -0
- package/examples/streaming-wallet-extension/src/components/LeftArrow.tsx +21 -0
- package/examples/streaming-wallet-extension/src/components/Loading.tsx +151 -0
- package/examples/streaming-wallet-extension/src/components/StreamingTransactionChip.tsx +95 -0
- package/examples/streaming-wallet-extension/src/components/TransactionRow.tsx +93 -0
- package/examples/streaming-wallet-extension/src/contentscript/content.ts +123 -0
- package/examples/streaming-wallet-extension/src/contentscript/lightsparkDemoDom.tsx +113 -0
- package/examples/streaming-wallet-extension/src/contentscript/videoElementParsers.ts +92 -0
- package/examples/streaming-wallet-extension/src/index.css +16 -0
- package/examples/streaming-wallet-extension/src/index.tsx +11 -0
- package/examples/streaming-wallet-extension/src/lightsparkClientProvider.tsx +26 -0
- package/examples/streaming-wallet-extension/src/react-app-env.d.ts +1 -0
- package/examples/streaming-wallet-extension/src/types/Messages.ts +17 -0
- package/examples/streaming-wallet-extension/tsconfig.json +20 -0
- package/package.json +87 -0
- package/src/auth/AccountTokenAuthProvider.ts +37 -0
- package/src/auth/index.ts +3 -0
- package/src/client.ts +759 -0
- package/src/graphql/BitcoinFeeEstimate.ts +13 -0
- package/src/graphql/CreateApiToken.ts +22 -0
- package/src/graphql/CreateInvoice.ts +18 -0
- package/src/graphql/CreateNodeWalletAddress.ts +13 -0
- package/src/graphql/CurrentAccount.ts +13 -0
- package/src/graphql/DecodeInvoice.ts +16 -0
- package/src/graphql/DeleteApiToken.ts +13 -0
- package/src/graphql/FundNode.ts +18 -0
- package/src/graphql/LightningFeeEstimateForInvoice.ts +21 -0
- package/src/graphql/LightningFeeEstimateForNode.ts +21 -0
- package/src/graphql/MultiNodeDashboard.ts +118 -0
- package/src/graphql/PayInvoice.ts +29 -0
- package/src/graphql/RecoverNodeSigningKey.ts +15 -0
- package/src/graphql/RequestWithdrawal.ts +25 -0
- package/src/graphql/SendPayment.ts +29 -0
- package/src/graphql/SingleNodeDashboard.ts +116 -0
- package/src/graphql/TransactionSubscription.ts +16 -0
- package/src/graphql/TransactionsForNode.ts +42 -0
- package/src/index.ts +5 -0
- package/src/objects/Account.ts +1222 -0
- package/src/objects/AccountToApiTokensConnection.ts +50 -0
- package/src/objects/AccountToChannelsConnection.ts +35 -0
- package/src/objects/AccountToNodesConnection.ts +62 -0
- package/src/objects/AccountToPaymentRequestsConnection.ts +50 -0
- package/src/objects/AccountToTransactionsConnection.ts +112 -0
- package/src/objects/ApiToken.ts +80 -0
- package/src/objects/BitcoinNetwork.ts +19 -0
- package/src/objects/BlockchainBalance.ts +102 -0
- package/src/objects/Channel.ts +283 -0
- package/src/objects/ChannelClosingTransaction.ts +150 -0
- package/src/objects/ChannelFees.ts +34 -0
- package/src/objects/ChannelOpeningTransaction.ts +150 -0
- package/src/objects/ChannelStatus.ts +25 -0
- package/src/objects/ChannelToTransactionsConnection.ts +86 -0
- package/src/objects/CreateApiTokenInput.ts +22 -0
- package/src/objects/CreateApiTokenOutput.ts +41 -0
- package/src/objects/CreateInvoiceInput.ts +27 -0
- package/src/objects/CreateInvoiceOutput.ts +21 -0
- package/src/objects/CreateNodeWalletAddressInput.ts +15 -0
- package/src/objects/CreateNodeWalletAddressOutput.ts +27 -0
- package/src/objects/CurrencyAmount.ts +55 -0
- package/src/objects/CurrencyUnit.ts +25 -0
- package/src/objects/DeleteApiTokenInput.ts +13 -0
- package/src/objects/DeleteApiTokenOutput.ts +23 -0
- package/src/objects/Deposit.ts +144 -0
- package/src/objects/Entity.ts +868 -0
- package/src/objects/FeeEstimate.ts +39 -0
- package/src/objects/FundNodeInput.ts +16 -0
- package/src/objects/FundNodeOutput.ts +28 -0
- package/src/objects/GraphNode.ts +110 -0
- package/src/objects/Hop.ts +108 -0
- package/src/objects/HtlcAttemptFailureCode.ts +65 -0
- package/src/objects/IncomingPayment.ts +141 -0
- package/src/objects/IncomingPaymentAttempt.ts +96 -0
- package/src/objects/IncomingPaymentAttemptStatus.ts +20 -0
- package/src/objects/IncomingPaymentToAttemptsConnection.ts +39 -0
- package/src/objects/Invoice.ts +226 -0
- package/src/objects/InvoiceData.ts +185 -0
- package/src/objects/InvoiceType.ts +15 -0
- package/src/objects/LightningFeeEstimateForInvoiceInput.ts +28 -0
- package/src/objects/LightningFeeEstimateForNodeInput.ts +25 -0
- package/src/objects/LightningFeeEstimateOutput.ts +33 -0
- package/src/objects/LightningTransaction.ts +393 -0
- package/src/objects/LightsparkNode.ts +377 -0
- package/src/objects/LightsparkNodePurpose.ts +17 -0
- package/src/objects/LightsparkNodeStatus.ts +29 -0
- package/src/objects/LightsparkNodeToChannelsConnection.ts +50 -0
- package/src/objects/Node.ts +273 -0
- package/src/objects/NodeAddress.ts +29 -0
- package/src/objects/NodeAddressType.ts +18 -0
- package/src/objects/NodeToAddressesConnection.ts +39 -0
- package/src/objects/OnChainTransaction.ts +318 -0
- package/src/objects/OutgoingPayment.ts +319 -0
- package/src/objects/OutgoingPaymentAttempt.ts +164 -0
- package/src/objects/OutgoingPaymentAttemptStatus.ts +18 -0
- package/src/objects/OutgoingPaymentAttemptToHopsConnection.ts +37 -0
- package/src/objects/OutgoingPaymentToAttemptsConnection.ts +39 -0
- package/src/objects/PageInfo.ts +31 -0
- package/src/objects/PayInvoiceInput.ts +33 -0
- package/src/objects/PayInvoiceOutput.ts +22 -0
- package/src/objects/PaymentFailureReason.ts +29 -0
- package/src/objects/PaymentRequest.ts +231 -0
- package/src/objects/PaymentRequestData.ts +183 -0
- package/src/objects/PaymentRequestStatus.ts +15 -0
- package/src/objects/Permission.ts +39 -0
- package/src/objects/RequestWithdrawalInput.ts +35 -0
- package/src/objects/RequestWithdrawalOutput.ts +24 -0
- package/src/objects/RichText.ts +19 -0
- package/src/objects/RoutingTransaction.ts +150 -0
- package/src/objects/RoutingTransactionFailureReason.ts +17 -0
- package/src/objects/Secret.ts +23 -0
- package/src/objects/SendPaymentInput.ts +30 -0
- package/src/objects/SendPaymentOutput.ts +22 -0
- package/src/objects/Transaction.ts +609 -0
- package/src/objects/TransactionFailures.ts +23 -0
- package/src/objects/TransactionStatus.ts +23 -0
- package/src/objects/TransactionType.ts +31 -0
- package/src/objects/TransactionUpdate.ts +67 -0
- package/src/objects/WalletDashboard.ts +32 -0
- package/src/objects/WebhookEventType.ts +15 -0
- package/src/objects/Withdrawal.ts +144 -0
- package/src/objects/WithdrawalMode.ts +15 -0
- package/src/objects/WithdrawalRequest.ts +224 -0
- package/src/objects/WithdrawalRequestStatus.ts +17 -0
- package/src/objects/WithdrawalRequestToChannelClosingTransactionsConnection.ts +57 -0
- package/src/objects/WithdrawalRequestToChannelOpeningTransactionsConnection.ts +57 -0
- package/src/objects/index.ts +108 -0
- package/tsconfig.json +5 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import dayjs from "dayjs";
|
|
2
|
+
import utc from "dayjs/plugin/utc";
|
|
3
|
+
import { v4 as uuid } from "uuid";
|
|
4
|
+
import { INSTANCE_ID_KEY } from "../common/storage";
|
|
5
|
+
import StreamingDemoAccountCredentials from "./StreamingDemoCredentials";
|
|
6
|
+
|
|
7
|
+
const GRAPH_QL_ENDPOINT = "https://api.lightspark.com/graphql/frontend";
|
|
8
|
+
|
|
9
|
+
dayjs.extend(utc);
|
|
10
|
+
|
|
11
|
+
const getInstanceID = (): Promise<string> => {
|
|
12
|
+
return new Promise<string>((resolve) => {
|
|
13
|
+
chrome.storage.local.get(INSTANCE_ID_KEY, (result) => {
|
|
14
|
+
if (result.instanceID) {
|
|
15
|
+
resolve(result.instanceID);
|
|
16
|
+
} else {
|
|
17
|
+
const instanceID = uuid();
|
|
18
|
+
chrome.storage.local.set({ [INSTANCE_ID_KEY]: instanceID }, () => {
|
|
19
|
+
resolve(instanceID);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const reserveStreamingDemoAccountCredentials =
|
|
27
|
+
async (): Promise<StreamingDemoAccountCredentials | null> => {
|
|
28
|
+
const response = await fetch(GRAPH_QL_ENDPOINT, {
|
|
29
|
+
method: "POST",
|
|
30
|
+
headers: {
|
|
31
|
+
"Content-Type": "application/json",
|
|
32
|
+
"X-Lightspark-Beta": "z2h0BBYxTA83cjW7fi8QwWtBPCzkQKiemcuhKY08LOo",
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify({
|
|
35
|
+
query: `mutation DemoAccountReserve {
|
|
36
|
+
DEMO_reserve_streaming_sats_account(input: { extension_id: "${await getInstanceID()}" }) {
|
|
37
|
+
signing_private_key
|
|
38
|
+
sender_node_id
|
|
39
|
+
receiver_node_id
|
|
40
|
+
client_secret
|
|
41
|
+
api_token {
|
|
42
|
+
id
|
|
43
|
+
client_id
|
|
44
|
+
name
|
|
45
|
+
}
|
|
46
|
+
expires_at
|
|
47
|
+
allocation_time
|
|
48
|
+
}
|
|
49
|
+
}`,
|
|
50
|
+
operationName: "DemoAccountReserve",
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
console.error("Failed to reserve demo account", response.statusText);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const responseJson = await response.json();
|
|
58
|
+
const data = responseJson.data.DEMO_reserve_streaming_sats_account;
|
|
59
|
+
if (!data) {
|
|
60
|
+
console.error(
|
|
61
|
+
"Failed to reserve demo account",
|
|
62
|
+
JSON.stringify(responseJson.errors)
|
|
63
|
+
);
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
clientId: data.api_token.client_id,
|
|
68
|
+
clientSecret: data.client_secret,
|
|
69
|
+
viewerWalletId: data.sender_node_id,
|
|
70
|
+
creatorWalletId: data.receiver_node_id,
|
|
71
|
+
viewerSigningKey: data.signing_private_key,
|
|
72
|
+
apiTokenId: data.api_token.id,
|
|
73
|
+
expiresAt: dayjs.utc(data.expires_at).utc().valueOf(),
|
|
74
|
+
allocationTime: data.allocation_time,
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const unreserveStreamingDemoAccountCredentials = async (
|
|
79
|
+
credentials: StreamingDemoAccountCredentials
|
|
80
|
+
): Promise<void> => {
|
|
81
|
+
await fetch(GRAPH_QL_ENDPOINT, {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: {
|
|
84
|
+
"Content-Type": "application/json",
|
|
85
|
+
"X-Lightspark-Beta": "z2h0BBYxTA83cjW7fi8QwWtBPCzkQKiemcuhKY08LOo",
|
|
86
|
+
},
|
|
87
|
+
body: JSON.stringify({
|
|
88
|
+
query: `mutation DemoAccountUnreserve {
|
|
89
|
+
DEMO_unreserve_streaming_sats_account(input: {
|
|
90
|
+
extension_id: "${await getInstanceID()}"
|
|
91
|
+
api_token_id: "${credentials.apiTokenId}"
|
|
92
|
+
}) {
|
|
93
|
+
success
|
|
94
|
+
}
|
|
95
|
+
}`,
|
|
96
|
+
operationName: "DemoAccountUnreserve",
|
|
97
|
+
}),
|
|
98
|
+
});
|
|
99
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import PlaybackRange from "./PlaybackRange";
|
|
2
|
+
|
|
3
|
+
export interface PaymentStrategy {
|
|
4
|
+
onPlayedRange(
|
|
5
|
+
previousRanges: PlaybackRange[],
|
|
6
|
+
newRanges: PlaybackRange[]
|
|
7
|
+
): number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class LinearPaymentStrategy implements PaymentStrategy {
|
|
11
|
+
private readonly paymentPerChunkMsats: number;
|
|
12
|
+
private readonly chunkSizeSec: number;
|
|
13
|
+
|
|
14
|
+
constructor(paymentPerChunkMsats: number, chunkSizeSec: number) {
|
|
15
|
+
this.paymentPerChunkMsats = paymentPerChunkMsats;
|
|
16
|
+
this.chunkSizeSec = chunkSizeSec;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private numberOfChunksInRanges(ranges: PlaybackRange[]): number {
|
|
20
|
+
const totalDuration = ranges.reduce(
|
|
21
|
+
(acc, range) => acc + range.duration(),
|
|
22
|
+
0
|
|
23
|
+
);
|
|
24
|
+
return Math.ceil(totalDuration / this.chunkSizeSec);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
onPlayedRange(
|
|
28
|
+
previousRanges: PlaybackRange[],
|
|
29
|
+
newRanges: PlaybackRange[]
|
|
30
|
+
): number {
|
|
31
|
+
const newChunks = this.numberOfChunksInRanges(newRanges);
|
|
32
|
+
const previousChunks = this.numberOfChunksInRanges(previousRanges);
|
|
33
|
+
const chunkDiff = newChunks - previousChunks;
|
|
34
|
+
return this.paymentPerChunkMsats * chunkDiff;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class PlaybackRange {
|
|
2
|
+
start: number;
|
|
3
|
+
end: number;
|
|
4
|
+
|
|
5
|
+
constructor(start: number, end: number) {
|
|
6
|
+
this.start = start;
|
|
7
|
+
this.end = end;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
mergeWith(other: PlaybackRange) {
|
|
11
|
+
let start = this.start;
|
|
12
|
+
let end = this.end;
|
|
13
|
+
if (other.start < this.start) {
|
|
14
|
+
start = other.start;
|
|
15
|
+
}
|
|
16
|
+
if (other.end > this.end) {
|
|
17
|
+
end = other.end;
|
|
18
|
+
}
|
|
19
|
+
return new PlaybackRange(start, end);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
isOverlapping(other: PlaybackRange) {
|
|
23
|
+
return this.start <= other.end && this.end >= other.start;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
duration() {
|
|
27
|
+
return this.end - this.start;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default PlaybackRange;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { InvoiceType, LightsparkClient } from "@lightsparkdev/lightspark-sdk";
|
|
2
|
+
import autoBind from "auto-bind";
|
|
3
|
+
|
|
4
|
+
class StreamingInvoiceHolder {
|
|
5
|
+
constructor() {
|
|
6
|
+
autoBind(this);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
public async createInvoice(
|
|
10
|
+
lightsparkClient: LightsparkClient,
|
|
11
|
+
creatorWalletId: string
|
|
12
|
+
): Promise<String | undefined> {
|
|
13
|
+
const encodedInvoice = await lightsparkClient.createInvoice(
|
|
14
|
+
creatorWalletId,
|
|
15
|
+
0,
|
|
16
|
+
"Streaming demo",
|
|
17
|
+
InvoiceType.AMP
|
|
18
|
+
);
|
|
19
|
+
await chrome.storage.local.set({ streamingInvoice: encodedInvoice });
|
|
20
|
+
return encodedInvoice;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public async getInvoiceData(): Promise<string | undefined> {
|
|
24
|
+
return (await chrome.storage.local.get("streamingInvoice"))
|
|
25
|
+
.streamingInvoice;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public async clearInvoice(): Promise<void> {
|
|
29
|
+
return await chrome.storage.local.remove("streamingInvoice");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default StreamingInvoiceHolder;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { LightsparkClient, Transaction } from "@lightsparkdev/lightspark-sdk";
|
|
2
|
+
import autoBind from "auto-bind";
|
|
3
|
+
import { Subscription } from "zen-observable-ts";
|
|
4
|
+
import { findActiveStreamingDemoTabs } from "../common/streamingTabs";
|
|
5
|
+
|
|
6
|
+
class TransactionObserver {
|
|
7
|
+
private isListening = false;
|
|
8
|
+
private subscription?: Subscription;
|
|
9
|
+
private readonly cachedTransactions = new Map<string, Transaction>();
|
|
10
|
+
|
|
11
|
+
constructor(private readonly lightsparkClient: LightsparkClient) {
|
|
12
|
+
autoBind(this);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public startListening(nodeId: string) {
|
|
16
|
+
console.log("Starting listening for transactions...");
|
|
17
|
+
if (this.isListening) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
this.isListening = true;
|
|
22
|
+
this.subscription = this.lightsparkClient
|
|
23
|
+
.listenToTransactions([nodeId])
|
|
24
|
+
.subscribe({
|
|
25
|
+
next: (transaction) => {
|
|
26
|
+
if (transaction) {
|
|
27
|
+
this.broadcastTransactions([transaction]);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public clearCache() {
|
|
34
|
+
this.cachedTransactions.clear();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public stopListening() {
|
|
38
|
+
console.log("Stopping listening for transactions...");
|
|
39
|
+
if (!this.isListening || !this.subscription) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
this.isListening = false;
|
|
44
|
+
this.subscription.unsubscribe();
|
|
45
|
+
this.subscription = undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private async broadcastTransactions(transactions: Transaction[]) {
|
|
49
|
+
transactions.forEach((transaction) => {
|
|
50
|
+
this.cachedTransactions.set(transaction.id, transaction);
|
|
51
|
+
});
|
|
52
|
+
findActiveStreamingDemoTabs().then((tabs) => {
|
|
53
|
+
if (tabs.length === 0) return;
|
|
54
|
+
chrome.tabs.sendMessage(tabs[0].id!, {
|
|
55
|
+
id: "transactions_updated",
|
|
56
|
+
transactions,
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
chrome.runtime.sendMessage({
|
|
60
|
+
id: "transactions_updated",
|
|
61
|
+
transactions: Array.from(this.cachedTransactions.values()),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export default TransactionObserver;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import PlaybackRange from "./PlaybackRange";
|
|
2
|
+
|
|
3
|
+
class VideoPlaybackRanges {
|
|
4
|
+
private playedRanges: Array<PlaybackRange> = [];
|
|
5
|
+
|
|
6
|
+
addPlayedRange(start: number, end: number) {
|
|
7
|
+
if (start > end) return;
|
|
8
|
+
const newRange = new PlaybackRange(start, end);
|
|
9
|
+
if (!this.mergeOverlappingRangeIfApplicable(newRange)) {
|
|
10
|
+
this.playedRanges.push(newRange);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
mergeOverlappingRangeIfApplicable(playbackRange: PlaybackRange): boolean {
|
|
15
|
+
for (let i = 0; i < this.playedRanges.length; i++) {
|
|
16
|
+
let range = this.playedRanges[i];
|
|
17
|
+
if (range.isOverlapping(playbackRange)) {
|
|
18
|
+
this.playedRanges[i] = range.mergeWith(playbackRange);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
getPlayedRanges() {
|
|
26
|
+
return this.playedRanges;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getPlayedDuration() {
|
|
30
|
+
let duration = 0;
|
|
31
|
+
this.playedRanges.forEach((range) => {
|
|
32
|
+
duration += range.end - range.start;
|
|
33
|
+
});
|
|
34
|
+
return duration;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default VideoPlaybackRanges;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import PlaybackRangesTracker from "./VideoPlaybackRanges";
|
|
2
|
+
|
|
3
|
+
class VideoProgressCache {
|
|
4
|
+
private videoProgressCache: { [videoID: string]: PlaybackRangesTracker };
|
|
5
|
+
private listeners: Array<(videoID: string) => void> = [];
|
|
6
|
+
private resolveWhenLoaded: () => void = () => {};
|
|
7
|
+
private whenLoadedPromise = new Promise<void>((resolve) => {
|
|
8
|
+
this.resolveWhenLoaded = resolve;
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
constructor() {
|
|
12
|
+
this.videoProgressCache = {};
|
|
13
|
+
this.readProgressFromStorage();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public async whenLoaded() {
|
|
17
|
+
return this.whenLoadedPromise;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public clear() {
|
|
21
|
+
this.videoProgressCache = {};
|
|
22
|
+
this.writeProgressToStorage();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
addProgress(videoID: string, start: number, end: number) {
|
|
26
|
+
if (!this.videoProgressCache[videoID]) {
|
|
27
|
+
this.videoProgressCache[videoID] = new PlaybackRangesTracker();
|
|
28
|
+
}
|
|
29
|
+
this.videoProgressCache[videoID].addPlayedRange(start, end);
|
|
30
|
+
console.log(`Added progress for ${videoID}: ${start} - ${end}`);
|
|
31
|
+
console.log(
|
|
32
|
+
`Current ranges: ${JSON.stringify(
|
|
33
|
+
this.videoProgressCache[videoID].getPlayedRanges()
|
|
34
|
+
)}`
|
|
35
|
+
);
|
|
36
|
+
this.listeners.forEach((listener) => listener(videoID));
|
|
37
|
+
this.writeProgressToStorage();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
listenForProgressChanges(listener: (videoID: string) => void) {
|
|
41
|
+
this.listeners.push(listener);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getPlayedDuration(videoID: string) {
|
|
45
|
+
if (!this.videoProgressCache[videoID]) {
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
return this.videoProgressCache[videoID].getPlayedDuration();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
getPlayedRanges(videoID: string) {
|
|
52
|
+
if (!this.videoProgressCache[videoID]) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
return this.videoProgressCache[videoID].getPlayedRanges();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
readProgressFromStorage() {
|
|
59
|
+
chrome.storage.local.get(null, (result) => {
|
|
60
|
+
Object.keys(result).forEach((key) => {
|
|
61
|
+
if (key.startsWith("video_")) {
|
|
62
|
+
const videoID = key.replace("video_", "");
|
|
63
|
+
const videoRanges = result[key]["playedRanges"];
|
|
64
|
+
this.videoProgressCache[videoID] = new PlaybackRangesTracker();
|
|
65
|
+
videoRanges.forEach((range: any) => {
|
|
66
|
+
this.videoProgressCache[videoID].addPlayedRange(
|
|
67
|
+
range.start,
|
|
68
|
+
range.end
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
this.resolveWhenLoaded();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
writeProgressToStorage() {
|
|
78
|
+
const newEntrys: any = {};
|
|
79
|
+
Object.keys(this.videoProgressCache).forEach((videoID) => {
|
|
80
|
+
const videoRanges = this.videoProgressCache[videoID];
|
|
81
|
+
newEntrys[`video_${videoID}`] = videoRanges;
|
|
82
|
+
});
|
|
83
|
+
chrome.storage.local.set(newEntrys);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export default VideoProgressCache;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccountTokenAuthProvider,
|
|
3
|
+
} from "@lightsparkdev/lightspark-sdk";
|
|
4
|
+
import AccountStorage from "../auth/AccountStorage";
|
|
5
|
+
import { unreserveStreamingDemoAccountCredentials } from "../auth/DemoAccountProvider";
|
|
6
|
+
import StreamingDemoAccountCredentials from "../auth/StreamingDemoCredentials";
|
|
7
|
+
import { clearStorageKeepingInstanceId } from "../common/storage";
|
|
8
|
+
import { findActiveStreamingDemoTabs } from "../common/streamingTabs";
|
|
9
|
+
import { getWalletClient } from "../lightsparkClientProvider";
|
|
10
|
+
import { onMessageReceived } from "./messageHandling";
|
|
11
|
+
import StreamingInvoiceHolder from "./StreamingInvoiceHolder";
|
|
12
|
+
import TransactionObserver from "./TransactionObserver";
|
|
13
|
+
import VideoProgressCache from "./VideoProgressCache";
|
|
14
|
+
import { StubAuthProvider } from "@lightsparkdev/core";
|
|
15
|
+
|
|
16
|
+
const progressCache = new VideoProgressCache();
|
|
17
|
+
const accountStorage = new AccountStorage();
|
|
18
|
+
const invoiceHolder = new StreamingInvoiceHolder();
|
|
19
|
+
const lightsparkClient = getWalletClient(accountStorage);
|
|
20
|
+
const transactionObserver = lightsparkClient.then(
|
|
21
|
+
(client) => new TransactionObserver(client)
|
|
22
|
+
);
|
|
23
|
+
let lastKnownStreamingTabId: number | undefined;
|
|
24
|
+
|
|
25
|
+
const setStreamingTabIdIfSender = (
|
|
26
|
+
message: { id: string },
|
|
27
|
+
sender: chrome.runtime.MessageSender
|
|
28
|
+
) => {
|
|
29
|
+
if (
|
|
30
|
+
message.id === "video_details" &&
|
|
31
|
+
sender.url?.includes("demos/streaming") &&
|
|
32
|
+
sender.tab &&
|
|
33
|
+
sender.tab?.id
|
|
34
|
+
) {
|
|
35
|
+
lastKnownStreamingTabId = sender.tab.id;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
40
|
+
Promise.all([lightsparkClient, transactionObserver]).then(
|
|
41
|
+
([lightsparkClient, transactionObserver]) => {
|
|
42
|
+
setStreamingTabIdIfSender(message, sender);
|
|
43
|
+
onMessageReceived(
|
|
44
|
+
message,
|
|
45
|
+
lightsparkClient,
|
|
46
|
+
progressCache,
|
|
47
|
+
invoiceHolder,
|
|
48
|
+
accountStorage,
|
|
49
|
+
transactionObserver,
|
|
50
|
+
sendResponse
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
return true;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
chrome.runtime.onMessageExternal.addListener(
|
|
58
|
+
(message, sender, sendResponse) => {
|
|
59
|
+
Promise.all([lightsparkClient, transactionObserver]).then(
|
|
60
|
+
([lightsparkClient, transactionObserver]) => {
|
|
61
|
+
setStreamingTabIdIfSender(message, sender);
|
|
62
|
+
onMessageReceived(
|
|
63
|
+
message,
|
|
64
|
+
lightsparkClient,
|
|
65
|
+
progressCache,
|
|
66
|
+
invoiceHolder,
|
|
67
|
+
accountStorage,
|
|
68
|
+
transactionObserver,
|
|
69
|
+
sendResponse
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const reloadOrOpenStreamingDemo = (openIfMissing: boolean = true) => {
|
|
78
|
+
findActiveStreamingDemoTabs().then(async (tabs) => {
|
|
79
|
+
console.log(`Found ${tabs.length} tabs to reload.`);
|
|
80
|
+
if (tabs.length > 0) {
|
|
81
|
+
chrome.tabs.update(tabs[0].id!, { active: true, highlighted: true });
|
|
82
|
+
chrome.tabs.reload(tabs[0].id!);
|
|
83
|
+
lastKnownStreamingTabId = tabs[0].id;
|
|
84
|
+
} else if (openIfMissing) {
|
|
85
|
+
// TODO: Replace with the final URL.
|
|
86
|
+
const newTab = await chrome.tabs.create({
|
|
87
|
+
url: "https://app.lightspark.com/demos/streaming",
|
|
88
|
+
active: true,
|
|
89
|
+
});
|
|
90
|
+
lastKnownStreamingTabId = newTab.id;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
chrome.runtime.onInstalled.addListener((details) => {
|
|
96
|
+
if (details.reason === "install") {
|
|
97
|
+
reloadOrOpenStreamingDemo();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
chrome.storage.local.onChanged.addListener((changes) => {
|
|
102
|
+
if (changes["credentials"]) {
|
|
103
|
+
console.log("Credentials changed, reloading tabs.");
|
|
104
|
+
lightsparkClient.then(async (lightsparkClient) => {
|
|
105
|
+
const credentials = changes["credentials"]
|
|
106
|
+
.newValue as StreamingDemoAccountCredentials;
|
|
107
|
+
if (credentials) {
|
|
108
|
+
lightsparkClient.setAuthProvider(
|
|
109
|
+
new AccountTokenAuthProvider(
|
|
110
|
+
credentials.clientId,
|
|
111
|
+
credentials.clientSecret
|
|
112
|
+
)
|
|
113
|
+
);
|
|
114
|
+
await lightsparkClient.loadNodeKey(
|
|
115
|
+
credentials.viewerWalletId,
|
|
116
|
+
credentials.viewerSigningKey
|
|
117
|
+
);
|
|
118
|
+
await invoiceHolder
|
|
119
|
+
.createInvoice(lightsparkClient, credentials.creatorWalletId)
|
|
120
|
+
.then((invoice) => {
|
|
121
|
+
console.log(`Created invoice: ${invoice}`);
|
|
122
|
+
});
|
|
123
|
+
} else {
|
|
124
|
+
await lightsparkClient.setAuthProvider(new StubAuthProvider());
|
|
125
|
+
await invoiceHolder.clearInvoice();
|
|
126
|
+
}
|
|
127
|
+
reloadOrOpenStreamingDemo(!!credentials);
|
|
128
|
+
});
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
chrome.tabs.onRemoved.addListener(async (tabId, _removeInfo) => {
|
|
135
|
+
if (tabId === lastKnownStreamingTabId) {
|
|
136
|
+
lastKnownStreamingTabId = undefined;
|
|
137
|
+
const account = await accountStorage.getAccountCredentials();
|
|
138
|
+
if (account) {
|
|
139
|
+
await unreserveStreamingDemoAccountCredentials(account);
|
|
140
|
+
}
|
|
141
|
+
await clearStorageKeepingInstanceId();
|
|
142
|
+
progressCache.clear();
|
|
143
|
+
(await transactionObserver).clearCache();
|
|
144
|
+
}
|
|
145
|
+
});
|