Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
martonlederer committed Aug 24, 2023
2 parents 451eafa + 0b81da4 commit 49e739e
Show file tree
Hide file tree
Showing 37 changed files with 721 additions and 433 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "arconnect",
"displayName": "ArConnect",
"version": "1.0.0",
"version": "1.0.2",
"description": "__MSG_extensionDescription__",
"author": "th8ta",
"packageManager": "yarn@1.22.18",
Expand All @@ -24,7 +24,6 @@
"alarms",
"contextMenus",
"tabs",
"declarativeNetRequest",
"webNavigation",
"notifications",
"<all_urls>"
Expand Down
40 changes: 40 additions & 0 deletions src/api/modules/dispatch/allowance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { freeDecryptedWallet } from "~wallets/encryption";
import type { Allowance } from "~applications/allowance";
import { defaultGateway } from "~applications/gateway";
import type { ModuleAppData } from "~api/background";
import type { JWKInterface } from "warp-contracts";
import { allowanceAuth } from "../sign/allowance";
import { signAuth } from "../sign/sign_auth";
import Arweave from "arweave";

/**
* Ensure allowance for dispatch
*/
export async function ensureAllowanceDispatch(
appData: ModuleAppData,
allowance: Allowance,
keyfile: JWKInterface,
price: number
) {
const arweave = new Arweave(defaultGateway);

// allowance or sign auth
try {
if (allowance.enabled) {
await allowanceAuth(allowance, appData.appURL, price);
} else {
// get address
const address = await arweave.wallets.jwkToAddress(keyfile);

await signAuth(
appData.appURL,
// @ts-expect-error
dataEntry.toJSON(),
address
);
}
} catch (e) {
freeDecryptedWallet(keyfile);
throw new Error(e?.message || e);
}
}
35 changes: 32 additions & 3 deletions src/api/modules/dispatch/dispatch.background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ import { cleanUpChunks, getChunks } from "../sign/chunks";
import { freeDecryptedWallet } from "~wallets/encryption";
import type { ModuleFunction } from "~api/background";
import { createData, ArweaveSigner } from "arbundles";
import { uploadDataToBundlr } from "./uploader";
import { getPrice, uploadDataToBundlr } from "./uploader";
import type { DispatchResult } from "./index";
import { signedTxTags } from "../sign/tags";
import { getActiveKeyfile } from "~wallets";
import { isString } from "typed-assert";
import Application from "~applications/application";
import browser from "webextension-polyfill";
import Arweave from "arweave";
import { ensureAllowanceDispatch } from "./allowance";
import { updateAllowance } from "../sign/allowance";

type ReturnType = {
arConfetti: string | false;
Expand Down Expand Up @@ -69,16 +71,32 @@ const background: ModuleFunction<ReturnType> = async (
// add ArConnect tags to the tag list
tags.push(...signedTxTags);

// get allowance
const allowance = await app.getAllowance();

// attempt to create a bundle
try {
// create bundlr tx as a data entry
const dataSigner = new ArweaveSigner(keyfile);
const dataEntry = createData(data, dataSigner, { tags });

// check allowance
const price = await getPrice(dataEntry, await app.getBundler());

await ensureAllowanceDispatch(
appData,
allowance,
decryptedWallet.keyfile,
price
);

// sign and upload bundler tx
await dataEntry.sign(dataSigner);
await uploadDataToBundlr(dataEntry, await app.getBundler());

// update allowance spent amount (in winstons)
await updateAllowance(appData.appURL, price);

// show notification
await signNotification(0, dataEntry.id, appData.appURL, "dispatch");

Expand All @@ -98,16 +116,27 @@ const background: ModuleFunction<ReturnType> = async (
for (const arcTag of signedTxTags) {
transaction.addTag(arcTag.name, arcTag.value);
}
// calculate price
const price = +transaction.reward + parseInt(transaction.quantity);

// ensure allowance
await ensureAllowanceDispatch(
appData,
allowance,
decryptedWallet.keyfile,
price
);

// sign and upload
await arweave.transactions.sign(transaction, keyfile);
const uploader = await arweave.transactions.getUploader(transaction);

while (!uploader.isComplete) {
await uploader.uploadChunk();
}

// calculate price
const price = +transaction.reward + parseInt(transaction.quantity);
// update allowance spent amount (in winstons)
await updateAllowance(appData.appURL, price);

// show notification
await signNotification(price, transaction.id, appData.appURL);
Expand Down
4 changes: 4 additions & 0 deletions src/api/modules/sign/allowance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ export async function allowanceAuth(
spendingLimitReached: !hasEnoughAllowance
});

// get updated allowance
const app = new Application(tabURL);
allowance = await app.getAllowance();

// call this function again, to check if the allowance
// was reset or updated
await allowanceAuth(allowance, tabURL, price);
Expand Down
7 changes: 6 additions & 1 deletion src/api/modules/sign/sign.background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ const background: ModuleFunction<BackgroundResult> = async (
if (allowance.enabled && activeWallet.type === "local") {
// authenticate user if the allowance
// limit is reached
await allowanceAuth(allowance, appData.appURL, price);
try {
await allowanceAuth(allowance, appData.appURL, price);
} catch (e) {
freeDecryptedWallet(keyfile);
throw new Error(e?.message || e);
}
} else {
// get address of keyfile
const addr =
Expand Down
36 changes: 33 additions & 3 deletions src/api/modules/sign_data_item/sign_data_item.background.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { allowanceAuth, updateAllowance } from "../sign/allowance";
import { isLocalWallet, isRawDataItem } from "~utils/assertions";
import { freeDecryptedWallet } from "~wallets/encryption";
import type { ModuleFunction } from "~api/background";
import { ArweaveSigner, createData } from "arbundles";
import Application from "~applications/application";
import { allowanceAuth } from "../sign/allowance";
import { getPrice } from "../dispatch/uploader";
import { getActiveKeyfile } from "~wallets";
import browser from "webextension-polyfill";
import { signAuth } from "../sign/sign_auth";
import Arweave from "arweave";

const background: ModuleFunction<number[]> = async (
appData,
Expand All @@ -29,6 +32,9 @@ const background: ModuleFunction<number[]> = async (
// create app
const app = new Application(appData.appURL);

// create arweave client
const arweave = new Arweave(await app.getGatewayConfig());

// get options and data
const { data, ...options } = dataItem;
const binaryData = new Uint8Array(data);
Expand All @@ -41,13 +47,37 @@ const background: ModuleFunction<number[]> = async (
const price = await getPrice(dataEntry, await app.getBundler());
const allowance = await app.getAllowance();

if (allowance.enabled) {
await allowanceAuth(allowance, appData.appURL, price);
// allowance or sign auth
try {
if (allowance.enabled) {
await allowanceAuth(allowance, appData.appURL, price);
} else {
// get address
const address = await arweave.wallets.jwkToAddress(
decryptedWallet.keyfile
);

await signAuth(
appData.appURL,
// @ts-expect-error
dataEntry.toJSON(),
address
);
}
} catch (e) {
freeDecryptedWallet(decryptedWallet.keyfile);
throw new Error(e?.message || e);
}

// sign item
await dataEntry.sign(dataSigner);

// update allowance spent amount (in winstons)
await updateAllowance(appData.appURL, price);

// remove keyfile
freeDecryptedWallet(decryptedWallet.keyfile);

return Array.from<number>(dataEntry.getRaw());
};

Expand Down
20 changes: 11 additions & 9 deletions src/api/modules/signature/signature.background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,22 @@ const background: ModuleFunction<number[]> = async (
isSignatureAlgorithm(algorithm);

// temporary whitelist
//const whitelisted = appData.appURL.match(getWhitelistRegExp());
const whitelisted = appData.appURL.match(getWhitelistRegExp());

//isNotNull(whitelisted, "The signature() API is deprecated.");
//isNotUndefined(whitelisted, "The signature() API is deprecated.");

// request user to authorize
try {
await authenticate({
type: "signature",
url: appData.appURL,
message: data
});
} catch {
throw new Error("User rejected the signature request");
if (!whitelisted) {
try {
await authenticate({
type: "signature",
url: appData.appURL,
message: data
});
} catch {
throw new Error("User rejected the signature request");
}
}

// grab the user's keyfile
Expand Down
2 changes: 1 addition & 1 deletion src/api/modules/signature/whitelist.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const whitelistedSites: RegExp[] = [
/app\.ardive\.io/,
/app\.ardrive\.io/,
/staging\.ardrive\.io/,
/dapp_ardrive\.ar-io\.dev/,
/og_dapp_ardrive\.ar-io\.dev/,
Expand Down
21 changes: 16 additions & 5 deletions src/applications/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,26 @@ export async function appConfigChangeListener(
for (const key in changes) {
// continue if not an app config change and
// if the app is added to the stored apps
if (!key.startsWith(PREFIX) || !storedApps.includes(key)) continue;

if (
!key.startsWith(PREFIX) ||
!storedApps.includes(key.replace(PREFIX, ""))
)
continue;

// get values and app
const { oldValue, newValue } = changes[key];
const { oldValue: storedOldValue, newValue: storedNewValue } = changes[key];
const appURL = key.replace(PREFIX, "");
const app = new Application(appURL);
// this was changed by atticus because values in storage are stored stringified
const oldValue = JSON.parse(
storedOldValue as unknown as string
) as InitAppParams;
const newValue = JSON.parse(
storedNewValue as unknown as string
) as InitAppParams;

// check if permission event emiting is needed

// get missing permissions
const missingPermissions = getMissingPermissions(
oldValue?.permissions || [],
Expand All @@ -62,6 +73,7 @@ export async function appConfigChangeListener(
]);

// compare gateway objects

if (
!compareGateways(oldValue?.gateway || {}, newValue?.gateway || {}) &&
hasGwPermission
Expand All @@ -76,7 +88,7 @@ export async function appConfigChangeListener(
}
}

// send permissins to the appropriate tab
// send permissions to the appropriate tab
await forEachTab(async (tab) => {
// return if no tab url is present
if (!tab?.url || !tab?.id) return;
Expand All @@ -85,7 +97,6 @@ export async function appConfigChangeListener(
const eventsForTab = events
.filter(({ appURL }) => getAppURL(tab.url) === appURL)
.map((e) => e.event);

// send the events
for (const event of eventsForTab) {
// trigger emiter
Expand Down
Loading

0 comments on commit 49e739e

Please sign in to comment.