-
Notifications
You must be signed in to change notification settings - Fork 54
Expand file tree
/
Copy pathprint.handler.ts
More file actions
129 lines (102 loc) · 4.01 KB
/
Copy pathprint.handler.ts
File metadata and controls
129 lines (102 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { WANDER_PRINTER_ID } from "~api/background/handlers/browser/printer/printer.constants";
import { uploadDataToTurbo } from "~api/modules/dispatch/uploader";
import { getActiveKeyfile, type DecryptedWallet } from "~wallets";
import { freeDecryptedWallet } from "~wallets/encryption";
import { createData, ArweaveSigner } from "@dha-team/arbundles";
import { concatGatewayURL } from "~gateways/utils";
import { findGateway } from "~gateways/wayfinder";
import browser from "webextension-polyfill";
import Arweave from "arweave";
import { signAuth } from "~api/modules/sign/sign_auth";
import { getActiveTab } from "~applications";
import { sleep } from "~utils/promises/sleep";
/**
* Print request (result) callback
*/
type PrintCallback = (result: string) => void;
/**
* Handles the request from the user to print the page to Arweave
*/
export async function handlePrint(printJob: chrome.printerProvider.PrintJob, resultCallback: PrintCallback) {
// only print for the Wander printer
if (printJob.printerId !== WANDER_PRINTER_ID) return;
// wallet
let decryptedWallet: DecryptedWallet;
try {
// build data blog
const data = new Blob([printJob.document], { type: printJob.contentType });
// get user wallet
decryptedWallet = await getActiveKeyfile();
if (decryptedWallet.type === "hardware") throw new Error("Cannot print with a hardware wallet.");
// extension manifest
const manifest = browser.runtime.getManifest();
// setup tags
const tags = [
{ name: "App-Name", value: manifest.name },
{ name: "App-Version", value: manifest.version },
{ name: "Type", value: "Print-Archive" },
{ name: "Content-Type", value: printJob.contentType },
{ name: "print:title", value: printJob.title },
{ name: "print:timestamp", value: new Date().getTime().toString() },
];
let transactionId: string;
// find a gateway to upload and display the result
const gateway = await findGateway({});
const arweave = Arweave.init(gateway);
// create data item
const dataSigner = new ArweaveSigner(decryptedWallet.keyfile);
const transactionData = new Uint8Array(await data.arrayBuffer());
const dataEntry = createData(transactionData, dataSigner, { tags });
// calculate reward for the transaction
const reward = await arweave.transactions.getPrice(transactionData.byteLength);
// get active tab
const activeTab = await getActiveTab();
await signAuth(
{
tabID: activeTab.id,
url: activeTab.url,
},
// @ts-expect-error
{
...dataEntry.toJSON(),
reward,
sizeInBytes: transactionData.byteLength,
},
decryptedWallet.address,
);
try {
// sign an upload data
await dataEntry.sign(dataSigner);
await uploadDataToTurbo(dataEntry, "https://turbo.ardrive.io");
await sleep(2000);
// this has to be one of FAILED, INVALID_DATA, INVALID_TICKET, OK
resultCallback("OK");
transactionId = dataEntry.id;
} catch (error) {
// sign & post if there is something wrong with turbo
const transaction = await arweave.createTransaction({ data: transactionData }, decryptedWallet.keyfile);
for (const tag of tags) {
transaction.addTag(tag.name, tag.value);
}
// sign and upload
await arweave.transactions.sign(transaction, decryptedWallet.keyfile);
const uploader = await arweave.transactions.getUploader(transaction);
while (!uploader.isComplete) {
await uploader.uploadChunk();
}
await sleep(2000);
// this has to be one of FAILED, INVALID_DATA, INVALID_TICKET, OK
resultCallback("OK");
transactionId = transaction.id;
}
// open in new tab
await chrome.tabs.create({
url: `${concatGatewayURL(gateway)}/${transactionId}`,
});
} catch (e) {
console.log("Printing failed:\n", e);
resultCallback("FAILED");
}
// free wallet from memory
if (decryptedWallet?.type == "local") freeDecryptedWallet(decryptedWallet.keyfile);
}