Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Merge pull request #356 from PureStake/master
Browse files Browse the repository at this point in the history
Patch 1.7.2
  • Loading branch information
PureBrent authored Jan 28, 2022
2 parents e00c94e + fd1e82a commit 16f27a8
Show file tree
Hide file tree
Showing 30 changed files with 626 additions and 318 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@
"scripts": {
"install:extension": "(cd ./packages/common && npm install); (cd ./packages/crypto && npm install); (cd ./packages/storage && npm install); (cd ./packages/ui && npm install); (cd ./packages/extension && npm install); (cd ./packages/dapp && npm install);",
"install:test": "(cd ./packages/test-project && npm install);",
"removelocks": "rm -rf ./package-lock.json && find -path \"./packages/*\" -name \"package-lock.json\" -not -path \"*/node_modules/*\" -exec rm -rf {} \\;",
"update": "npm update && find -maxdepth 2 -path \"./packages/*\" -exec npm update {} \\;",
"removelocks": "rm -rf ./package-lock.json && find . -path \"./packages/*\" -name \"package-lock.json\" -not -path \"*/node_modules/*\" -exec rm -rf {} \\;",
"removemodules": "rm -rf node_modules && find . -path \"./packages/*\" -name \"node_modules*\" -exec rm -rf {} \\;",
"build": "(cd ./packages/common && npm run build); (cd ./packages/crypto && npm run build); (cd ./packages/dapp && npm run build); (cd ./packages/storage && npm run build); (cd ./packages/ui && npm run build); (cd ./packages/extension && npm run build);",
"build:ui": "cd ./packages/ui && npm run build && cp -r ./dist/* ../../dist/",
"build:extension": "cd ./packages/extension && npm run build && cp -r ./dist/* ../../dist/",
"clean": "rm -rf ./dist/* && rm -rf ./packages/common/dist/* && rm -rf ./packages/crypto/dist/* && rm -rf ./packages/dapp/dist/* && rm -rf ./packages/extension/dist/* && rm -rf ./packages/storage/dist/* && rm -rf ./packages/ui/dist/* && rm -rf ./packages/dapp/lib/*",
"clean": "rm -rf ./dist && rm -rf ./packages/common/dist && rm -rf ./packages/crypto/dist && rm -rf ./packages/dapp/dist && rm -rf ./packages/extension/dist && rm -rf ./packages/storage/dist && rm -rf ./packages/ui/dist && rm -rf ./packages/dapp/dist",
"copy": "mkdir -p ./dist && cp -r ./packages/extension/dist/* dist/ && cp -r ./packages/ui/dist/* dist/ && cp -r ./packages/dapp/dist/* dist/ && mkdir -p ./dist/docs && cp -r ./docs/* dist/docs/",
"prebuild": "rm -rf ./dist/*",
"postbuild": "npm run copy",
"postinstall": "npm run install:extension && npm run install:test",
"rebuild": "npm run clean && npm run removelocks && npm install && npm run update && npm run build",
"rebuild": "npm run clean && npm run removelocks && npm run removemodules && npm install && npm run build",
"coveragetest": "(cd ./packages/test-project && npm run coveragetest)",
"test": "npm run test:unit && npm run test:e2e",
"test:unit": "(cd ./packages/crypto && npm run test) && (cd ./packages/extension && npm run test) && (cd ./packages/ui && npm run test) && (cd ./packages/dapp && npm run test) && (cd ./packages/common && npm run test)",
Expand Down
13 changes: 13 additions & 0 deletions packages/common/src/interfaces/axfer_close.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { IBaseTx } from './baseTx';

///
// Mapping interface of allowable fields for axfer transactions.
///

// prettier-ignore
export interface IAssetCloseTx extends IBaseTx {
type: string, //"axfer"
assetIndex: number, //uint64 "xaid" The unique ID of the asset to be transferred.
closeRemainderTo: string, //Address "aclose" Specify this field to remove the asset holding from the sender account and reduce the account's minimum balance.
to: string, //Address
}
1 change: 1 addition & 0 deletions packages/common/src/messaging/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export enum JsonRpcMethod {
AssetDetails = 'asset-details',
AssetsAPIList = 'assets-api-list',
AssetsVerifiedList = 'assets-verified-list',
AssetOptOut = 'asset-opt-out',
SignSendTransaction = 'sign-send-transaction',
ChangeLedger = 'change-ledger',
SaveNetwork = 'save-network',
Expand Down
55 changes: 37 additions & 18 deletions packages/extension/src/background/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ export class Settings {
}

// Setup port splits for algod and indexer - used in sandbox installs
const parsedAlgodUrlObj = parseUrlServerAndPort(ledger.algodUrl)
const parsedAlgodUrlObj = parseUrlServerAndPort(ledger.algodUrl);
const parsedIndexerUrlObj = parseUrlServerAndPort(ledger.indexerUrl);

// Add algod links
const injectedAlgod = {
url: parsedAlgodUrlObj.server || `${defaultUrl}/algod`,
Expand All @@ -111,15 +111,14 @@ export class Settings {
headers: headersIndexer || headers,
};

if (isCheckOnly) {
if (isCheckOnly) {
return {
'algod': injectedAlgod,
'indexer': injectedIndexer
}
}
else {
algod: injectedAlgod,
indexer: injectedIndexer,
};
} else {
this.backend_settings.InjectedNetworks[ledger.name][API.Algod] = injectedAlgod;
this.backend_settings.InjectedNetworks[ledger.name][API.Indexer] = injectedIndexer;
this.backend_settings.InjectedNetworks[ledger.name][API.Indexer] = injectedIndexer;
this.backend_settings.InjectedNetworks[ledger.name].headers = headers;
}
}
Expand All @@ -132,20 +131,40 @@ export class Settings {
};

this.setInjectedHeaders(ledger);
logging.log(`Added Network:\n${JSON.stringify(this.backend_settings.InjectedNetworks[ledger.name],null,1)}`,2);
logging.log(
`Added Network:\n${JSON.stringify(
this.backend_settings.InjectedNetworks[ledger.name],
null,
1
)}`,
2
);
}

public static updateInjectedNetwork(updatedLedger: LedgerTemplate) {
this.backend_settings.InjectedNetworks[updatedLedger.name].genesisId = updatedLedger.genesisId;
this.backend_settings.InjectedNetworks[updatedLedger.name].symbol = updatedLedger.symbol;
this.backend_settings.InjectedNetworks[updatedLedger.name].genesisHash =
public static updateInjectedNetwork(updatedLedger: LedgerTemplate, previousName: string = '') {
const targetName = updatedLedger.uniqueName;

if (previousName) {
this.deleteInjectedNetwork(previousName);
this.backend_settings.InjectedNetworks[targetName] = {};
}
this.backend_settings.InjectedNetworks[targetName].genesisId = updatedLedger.genesisId;
this.backend_settings.InjectedNetworks[targetName].symbol = updatedLedger.symbol;
this.backend_settings.InjectedNetworks[targetName].genesisHash =
updatedLedger.genesisHash;
this.backend_settings.InjectedNetworks[updatedLedger.name].algodUrl = updatedLedger.algodUrl;
this.backend_settings.InjectedNetworks[updatedLedger.name].indexerUrl =
this.backend_settings.InjectedNetworks[targetName].algodUrl = updatedLedger.algodUrl;
this.backend_settings.InjectedNetworks[targetName].indexerUrl =
updatedLedger.indexerUrl;
this.setInjectedHeaders(updatedLedger);

logging.log(`Updated Network:\n${JSON.stringify(this.backend_settings.InjectedNetworks[updatedLedger.name],null,1)}`,2);
logging.log(
`Updated Network:\n${JSON.stringify(
this.backend_settings.InjectedNetworks[targetName],
null,
1
)}`,
2
);
}

public static getBackendParams(ledger: string, api: API) {
Expand All @@ -169,7 +188,7 @@ export class Settings {
}

public static checkNetwork(ledger: LedgerTemplate) {
const networks = this.setInjectedHeaders(ledger, true);
const networks = this.setInjectedHeaders(ledger, true);
return networks;
}
}
174 changes: 150 additions & 24 deletions packages/extension/src/background/messaging/internalMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ export class InternalMethods {
const sessTxn = session.txnWrap.body.params.transaction;

// Set the fee to the estimate we showed on the screen for validation if there is one.
if(session.txnWrap.body.params.estimatedFee) {
if (session.txnWrap.body.params.estimatedFee) {
sessTxn['fee'] = session.txnWrap.body.params.estimatedFee;
}
const sessTxnEntries = Object.entries(sessTxn).sort();
Expand Down Expand Up @@ -371,18 +371,18 @@ export class InternalMethods {

// If v2 then it needs to return an array
if (session.txnWrap?.body?.params?.transactionsOrGroups) {
message.response = [{
blob: request.body.params.txn
}];
}
else {
message.response = [
{
blob: request.body.params.txn,
},
];
} else {
message.response = {
blob: request.body.params.txn
blob: request.body.params.txn,
};
}

sendResponse({ message: message });

}
// If this is a ui transaction then we need to also submit
else if (session.txnWrap.source === 'ui') {
Expand Down Expand Up @@ -678,6 +678,130 @@ export class InternalMethods {
return true;
}

public static [JsonRpcMethod.AssetOptOut](request: any, sendResponse: Function) {
const { ledger, address, passphrase, id } = request.body.params;
this._encryptionWrap = new encryptionWrap(passphrase);
const algod = this.getAlgod(ledger);

this._encryptionWrap.unlock(async (unlockedValue: any) => {
if ('error' in unlockedValue) {
sendResponse(unlockedValue);
return false;
}
let account;

// Find address to send algos from
for (var i = unlockedValue[ledger].length - 1; i >= 0; i--) {
if (unlockedValue[ledger][i].address === address) {
account = unlockedValue[ledger][i];
break;
}
}

const params = await algod.getTransactionParams().do();
const txn = {
type: 'axfer',
from: address,
to: address,
closeRemainderTo: address,
assetIndex: id,
fee: params.fee,
firstRound: params.firstRound,
lastRound: params.lastRound,
genesisID: params.genesisID,
genesisHash: params.genesisHash,
};

let transactionWrap: BaseValidatedTxnWrap = undefined;
try {
transactionWrap = getValidatedTxnWrap(txn, txn['type']);
} catch (e) {
logging.log(`Validation failed. ${e}`);
sendResponse({ error: `Validation failed. ${e}` });
return;
}
if (!transactionWrap) {
// We don't have a transaction wrap. We have an unknow error or extra fields, reject the transaction.
logging.log(
'A transaction has failed because of an inability to build the specified transaction type.'
);
sendResponse({
error:
'A transaction has failed because of an inability to build the specified transaction type.',
});
return;
} else if (
transactionWrap.validityObject &&
Object.values(transactionWrap.validityObject).some(
(value) => value['status'] === ValidationStatus.Invalid
)
) {
// We have a transaction that contains fields which are deemed invalid. We should reject the transaction.
const e =
'One or more fields are not valid. Please check and try again.\n' +
Object.values(transactionWrap.validityObject)
.filter((value) => value['status'] === ValidationStatus.Invalid)
.map((vo) => vo['info']);
sendResponse({ error: e });
return;
} else {
// We have a transaction which does not contain invalid fields,
// but may still contain fields that are dangerous
// or ones we've flagged as needing to be reviewed.
// Perform a change based on if this is a ledger device account
if (account.isHardware) {
// TODO: Temporary workaround by adding min-fee for estimate calculations since it's not in the sdk get params.
params['min-fee'] = 1000;
calculateEstimatedFee(transactionWrap, params);

// Pass the transaction wrap we can pass to the
// central sign ledger function for consistency
this[JsonRpcMethod.LedgerSignTransaction](
{ source: 'ui', body: { params: transactionWrap } },
(response) => {
// We only have to worry about possible errors here so we can ignore the created tab
if ('error' in response) {
sendResponse(response);
} else {
// Respond with a 0 tx id so that the page knows not to try and show it.
sendResponse({ txId: 0 });
}
}
);

// Return to close connection
return true;
} else {
// We can use a modified popup to allow the normal flow, but require extra scrutiny.
const recoveredAccount = algosdk.mnemonicToSecretKey(account.mnemonic);
let signedTxn;
try {
const builtTx = buildTransaction(txn);
signedTxn = {
txID: builtTx.txID().toString(),
blob: builtTx.signTxn(recoveredAccount.sk),
};
} catch (e) {
sendResponse({ error: e.message });
return false;
}

algod
.sendRawTransaction(signedTxn.blob)
.do()
.then((resp: any) => {
sendResponse({ txId: resp.txId });
})
.catch((e: any) => {
sendResponse({ error: e.message });
});
}
}
});

return true;
}

public static [JsonRpcMethod.SignSendTransaction](request: any, sendResponse: Function) {
const { ledger, address, passphrase, txnParams } = request.body.params;
this._encryptionWrap = new encryptionWrap(passphrase);
Expand Down Expand Up @@ -891,9 +1015,10 @@ export class InternalMethods {

public static [JsonRpcMethod.SaveNetwork](request: any, sendResponse: Function) {
try {
const params = request.body.params;
// If we have a passphrase then we are modifying.
// There may be accounts attatched, if we match on a unique name, we should update.
if (request.body.params['passphrase'] !== undefined) {
if (params['passphrase'] !== undefined) {
this._encryptionWrap = new encryptionWrap(request.body.params['passphrase']);
this._encryptionWrap.unlock((unlockedValue: any) => {
if ('error' in unlockedValue) {
Expand All @@ -902,14 +1027,17 @@ export class InternalMethods {
// We have evaluated the passphrase and it was valid.
});
}

const previousName = params['previousName'].toLowerCase();
const targetName = previousName ? previousName : params['name'].toLowerCase();
const addedLedger = new LedgerTemplate({
name: request.body.params['name'],
genesisId: request.body.params['genesisId'],
genesisHash: request.body.params['genesisHash'],
symbol: request.body.params['symbol'],
algodUrl: request.body.params['algodUrl'],
indexerUrl: request.body.params['indexerUrl'],
headers: request.body.params['headers'],
name: params['name'],
genesisId: params['genesisId'],
genesisHash: params['genesisHash'],
symbol: params['symbol'],
algodUrl: params['algodUrl'],
indexerUrl: params['indexerUrl'],
headers: params['headers'],
});

// Specifically get the base ledgers to check and prevent them from being overriden.
Expand All @@ -919,19 +1047,17 @@ export class InternalMethods {
const comboLedgers = [...availiableLedgers];

// Add the new ledger if it isn't there.
if (!comboLedgers.some((cledg) => cledg.uniqueName === addedLedger.uniqueName)) {
if (!comboLedgers.some((cledg) => cledg.uniqueName === targetName)) {
comboLedgers.push(addedLedger);

// Also add the ledger to the injected ledgers in settings
Settings.addInjectedNetwork(addedLedger);
}
// If the new ledger name does exist, we sould update the values as long as it is not a default ledger.
else {
const matchingLedger = comboLedgers.find(
(cledg) => cledg.uniqueName === addedLedger.uniqueName
);
} else {
// If the new ledger name does exist, we sould update the values as long as it is not a default ledger.
const matchingLedger = comboLedgers.find((cledg) => cledg.uniqueName === targetName);
if (!defaultLedgers.some((dledg) => dledg.uniqueName === matchingLedger.uniqueName)) {
Settings.updateInjectedNetwork(addedLedger);
Settings.updateInjectedNetwork(addedLedger, previousName);
matchingLedger.name = addedLedger.name;
matchingLedger.genesisId = addedLedger.genesisId;
matchingLedger.symbol = addedLedger.symbol;
matchingLedger.genesisHash = addedLedger.genesisHash;
Expand Down
3 changes: 3 additions & 0 deletions packages/extension/src/background/messaging/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1463,6 +1463,9 @@ export class Task {
[JsonRpcMethod.AssetsVerifiedList]: (request: any, sendResponse: Function) => {
return InternalMethods[JsonRpcMethod.AssetsVerifiedList](request, sendResponse);
},
[JsonRpcMethod.AssetOptOut]: (request: any, sendResponse: Function) => {
return InternalMethods[JsonRpcMethod.AssetOptOut](request, sendResponse);
},
[JsonRpcMethod.SignSendTransaction]: (request: any, sendResponse: Function) => {
return InternalMethods[JsonRpcMethod.SignSendTransaction](request, sendResponse);
},
Expand Down
Loading

0 comments on commit 16f27a8

Please sign in to comment.