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 #153 from PureStake/develop
Browse files Browse the repository at this point in the history
Release 1.2.0
  • Loading branch information
purestaketdb authored Nov 18, 2020
2 parents 32f65e9 + 5ccfafc commit 8c0cfac
Show file tree
Hide file tree
Showing 32 changed files with 593 additions and 155 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/zip-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
id: zip_up
run: zip -r AlgoSigner.zip ./dist/*
- name: Upload
uses: actions/upload-release-asset@v1.1.0
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
Expand Down
58 changes: 23 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ![AlgoSigner](media/algosigner-wallet-banner-3.png)

An open-source Algorand wallet browser extension that permits dApp communication for signing Algorand transactions - available for Chrome initially.
An open-source Algorand wallet browser extension that permits dApp communication for signing Algorand transactions available for Chrome initially.

## Chrome Extension Store
The extension is available on the [Chrome Extension Store](https://chrome.google.com/webstore/detail/algosigner/kmmolakhbgdlpkjkcjkebenjheonagdm)
Expand All @@ -9,36 +9,23 @@ _This is the preferred solution for end-users, updates will be automatically ins

Developers working with dApps may also install directly from the release package, or by downloading the project and building it.

## 1.1.0 Update
The latest release introduces several key new features for users and dApp developers.
## 1.2.0 Update
The latest release brings:

### Asset Support in the UI
Assets have always been displayed in the UI, now you may find new assets, opt-in to them, and transfer them right in the UI.
- Support for dApps to submit Atomic (group) transactions
- Support for dApps to submit application creation transactions
- Change to how fee's and flat fees are handled in the UI and in the signing step
- Minor UI updates (block duplicate accounts, block multiple asset optins, network selector properly closing)

### Asset Support for dApps
dApps were previously able to send in basic asset transactions to be signed by AlgoSigner. Support has now been added for all asset transaction types with accompanying UI notices.
### Atomic Transactions
* Grouped transactions intended for atomic transaction functionality need to be grouped outside of AlgoSigner, but can be signed individually.
* The grouped transactions need to have their binary components concatenated to be accepted in the AlgoSigner send method.
* An example of this can be seen in the [existing sample dApp group test](https://purestake.github.io/algosigner-dapp-example/tx-test/signTesting.html).

* Clawback added
* Destroy capability allowed for `acfg`
* Close-to supported in `axfer`
## Roadmap
The next feature release will bring support for dApps to submit multi-signature transactions for signing. Planned for mid-late December.

### Application Transaction Support for dApps
dApp developers may now send in application transactions to be signed. This support is new and subject to change in subsequent releases. Please read the updated [dApp Integration Guide](docs/dApp-integration.md) for instructions on working with these transaction types.

### Additional dApp support

* Support has been enabled for `close-to` transactions.
* Transaction validation errors will now provide more detailed messages on causes

### UI Transactions
With the addition of support for `close-to` transactions, new warning messages will display in the UI when dApps send in pay transactions that are potentially dangerous.

The signing window will also now reflect better the ledger the dApp is asking the user to sign a transaction for. A new label is present in dark blue for Testnet and orange for Mainnet

### Sample dApp and dApp Tests

* Signing app - New sample dApp for [demonstrating transaction signing](https://purestake.github.io/algosigner-dapp-example/tx-test/signTesting.html)
* Updates to the [existing sample dApp](https://purestake.github.io/algosigner-dapp-example/) demonstrating pending lookup and asset search
Following on will be a feature release permitting the addition and configuration of networks, planned for early 2021.

## Decentralized Applications
As a browser extension, AlgoSigner opens the door for developers to build DeFi applications on Algorand by providing a secure way to add transaction capabilities. This enables developers to initiate transactions and accept ALGOs seamlessly, without jeopardizing the security of their users’ secrets.
Expand All @@ -54,10 +41,11 @@ DApp users can trust AlgoSigner to:

- Read [dApp Integration Guide](docs/dApp-integration.md)
- Read [Sample dApp project](https://github.com/PureStake/algosigner-dapp-example)
- Try [Sample Signing Scenarios](https://purestake.github.io/algosigner-dapp-example/tx-test/signTesting.html)
- Try [Interactive dApp](https://purestake.github.io/algosigner-dapp-example/)

## Project Structure
There are multiple packages in the project that combine to build the overall extension. Each component package is designed so that it's functionality doesn't require the rebuild of other packages and will be combined to build the deployable extension.
There are multiple packages in the project that combine to build the overall extension. Each component package is designed so that its functionality doesn't require the rebuild of other packages and will be combined to build the deployable extension.

*https://github.com/PureStake*
* algosigner-> // Base project folder
Expand All @@ -69,7 +57,7 @@ There are multiple packages in the project that combine to build the overall ext
* extension-> // Extension definition and core files
* storage -> // Handles saving and loading of account information
* test-project -> // Test wrapper for the package files
* ui-> // Front end application for interaction within the extension interface \
* ui-> // Front end application for interaction within the extension interface
* manifest.json // Extension definition file
* package.json // Algosigner package, required packages, and scripts to build the project
* readme.md // Project overview
Expand All @@ -83,26 +71,26 @@ The ./dist/ folder is the only required folder to install the extension yourself

- Clone the repository locally
- Run `npm install` in the root folder
- Run `npm run build` in the root folder - this creates the `dist` folder
- Open Chrome Browser - go to `chrome://extensions/`
- Run `npm run build` in the root folder this creates the `dist` folder
- Open Chrome browser — go to `chrome://extensions/`
- Enable developer mode
- Select `Load Unpacked` and choose the just created `dist` folder
- AlgoSigner is now installed and available

## Install from zip
The latest built zip is available for download on the releases page -
The latest built zip is available for download on the releases page

Note - this is not recommended for non-developers and never for production purposes, extreme caution should be taken with installing any wallet.
NoteL this is not recommended for non-developers and should never be used for production purposes. Extreme caution should be taken when installing any wallet.

### Prerequisites
- Installation of the Chrome Browser
- Installation of the Chrome browser
- File unzip program
- Local file system write permissions
- Access to set developer mode in Chrome and install unpacked extensions

### Process
- Unzip `AlgoSigner.zip` file to local file system
- Open Chrome Browser and go to `chrome://extensions/`
- Open Chrome browser and go to `chrome://extensions/`
- Enable developer mode
- Select `Load Unpacked` and choose the unzipped `dist` folder
- AlgoSigner is now installed and available
Expand Down
8 changes: 7 additions & 1 deletion docs/dApp-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ In the following example, _txParams_ is set by a previous call to _AlgoSigner.al
let txn = {
from: accounts[0].address,
to: 'PBZHOKKNBUCCDJB7KB2KLHUMWCGAMBXZKGBFGGBHYNNXFIBOYI7ONYBWK4',
fee: txParams['min-fee'],
fee: txParams['fee'],
type: 'pay',
amount: amount,
firstRound: txParams['last-round'],
Expand All @@ -176,6 +176,12 @@ Due to limitations in Chrome internal messaging, AlgoSigner encodes the transact
- [Python](https://github.com/PureStake/algosigner-dapp-example/blob/master/python/pythonTransaction.py)
- [NodeJS](https://github.com/PureStake/algosigner-dapp-example/blob/master/nodeJs/nodeJsTransaction.js)

#### Atomic Transactions
* Grouped transactions intended for atomic transaction functionality need to be grouped outside of AlgoSigner, but can be signed individually.
* The grouped transactions need to have their binary components concatenated to be accepted in the AlgoSigner send method.
* An example of this can be seen in the [existing sample dApp group test](https://purestake.github.io/algosigner-dapp-example/tx-test/signTesting.html).


### AlgoSigner.send({ ledger: ‘MainNet|TestNet’, txBlob })
Send a base64 encoded signed transaction blob to AlgoSigner to transmit to the Network.

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "algosigner",
"version": "1.1.0",
"version": "1.2.0",
"author": "https://developer.purestake.io",
"description": "Sign Algorand transactions in your browser with PureStake.",
"keywords": [
Expand Down
2 changes: 1 addition & 1 deletion packages/common/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@algosigner/common",
"version": "1.1.0",
"version": "1.2.0",
"author": "https://developer.purestake.io",
"description": "Common library functions for AlgoSigner.",
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/interfaces/baseTx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export interface IBaseTx {
lease?: any, //[32]byte "lx" A lease enforces mutual exclusion of transactions. If this field is nonzero, then once the transaction is confirmed, it acquires the lease identified by the (Sender, Lease) pair of the transaction until the LastValid round passes. While this transaction possesses the lease, no other transaction specifying this lease can be confirmed. A lease is often used in the context of Algorand Smart Contracts to prevent replay attacks. (Buffer is created from the provided value)
//txType //string "type" Specifies the type of transaction. This value is automatically generated using any of the developer tools.
reKeyTo?: any, //string "rekey" Remapped to reKeyTo for algosdk alignment
flatFee?: boolean
}

2 changes: 1 addition & 1 deletion packages/crypto/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "algosigner-crypto",
"version": "1.1.0",
"version": "1.2.0",
"author": "https://developer.purestake.io",
"description": "Cryptographic wrapper for saving and retrieving extention information in Algosigner.",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/dapp/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@algosigner/dapp",
"version": "1.1.0",
"version": "1.2.0",
"author": "https://developer.purestake.io",
"description": "Sample DAPP for use with AlgoSigner.",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/extension/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "AlgoSigner",
"author": "https://developer.purestake.io",
"version": "1.1.0",
"version": "1.2.0",
"description": "Algorand Wallet Extension | Send & Receive ALGOs | Sign dApp Transactions",
"icons": {
"48": "icon.png"
Expand Down
4 changes: 2 additions & 2 deletions packages/extension/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "algosigner-extension",
"version": "1.1.0",
"version": "1.2.0",
"author": "https://developer.purestake.io",
"description": "Sign Algorand transactions in your browser with PureStake.",
"keywords": [
Expand All @@ -18,7 +18,7 @@
"webpack-cli": "^3.3.12"
},
"dependencies": {
"algosdk": "^1.7.2"
"algosdk": "1.7.2"
},
"scripts": {
"build": "npm run clean && npm run bundle && npm run copy",
Expand Down
17 changes: 13 additions & 4 deletions packages/extension/src/background/messaging/internalMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import AssetsDetailsHelper from '../utils/assetsDetailsHelper';
import { initializeCache } from '../utils/helper';
import { ValidationStatus } from '../utils/validator';
import { getValidatedTxnWrap } from "../transaction/actions";
import { buildTransaction } from '../utils/transactionBuilder';
const algosdk = require("algosdk");

const session = new Session;
Expand Down Expand Up @@ -234,9 +235,15 @@ export class InternalMethods {
this._encryptionWrap = new encryptionWrap(request.body.params.passphrase);

try {
var recoveredAccount = algosdk.mnemonicToSecretKey(mnemonic);
var recoveredAccountAddress = algosdk.mnemonicToSecretKey(mnemonic).addr;
var existingAccounts = session.wallet[ledger];
for (let i = 0; i < existingAccounts.length; i++) {
if (existingAccounts[i].address === recoveredAccountAddress) {
throw new Error(`Account already exists in ${ledger} wallet.`);
}
}
var newAccount = {
address: recoveredAccount.addr,
address: recoveredAccountAddress,
mnemonic: mnemonic,
name: name
};
Expand Down Expand Up @@ -481,7 +488,8 @@ export class InternalMethods {
// or ones we've flagged as needing to be reviewed. We can use a modified popup to allow the normal flow, but require extra scrutiny.
let signedTxn;
try {
signedTxn = algosdk.signTransaction(txn, recoveredAccount.sk);
let builtTx = buildTransaction(txn);
signedTxn = {"txID": builtTx.txID().toString(), "blob": builtTx.signTxn(recoveredAccount.sk)};
} catch(e) {
sendResponse({error: e.message});
return;
Expand All @@ -498,7 +506,8 @@ export class InternalMethods {
} else {
let signedTxn;
try {
signedTxn = algosdk.signTransaction(txn, recoveredAccount.sk);
let builtTx = buildTransaction(txn);
signedTxn = {"txID": builtTx.txID().toString(), "blob": builtTx.signTxn(recoveredAccount.sk)};
} catch(e) {
sendResponse({error: e.message});
return;
Expand Down
35 changes: 26 additions & 9 deletions packages/extension/src/background/messaging/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Settings } from '../config';
import {extensionBrowser} from '@algosigner/common/chrome';
import {logging} from '@algosigner/common/logging';
import { InvalidTransactionStructure } from "../../errors/validation";
import { buildTransaction } from '../utils/transactionBuilder';

export class Task {

Expand Down Expand Up @@ -422,23 +423,39 @@ export class Task {
// Application transactions only
if(txn && txn.type == 'appl'){
if('appApprovalProgram' in txn){
txn.appApprovalProgram = Uint8Array.from(Buffer.from(txn.appApprovalProgram));
try {
txn.appApprovalProgram = Uint8Array.from(Buffer.from(txn.appApprovalProgram,'base64'));
}
catch{
message.error = 'Error trying to parse appApprovalProgram into a Uint8Array value.';
}
}
if('appClearProgram' in txn){
txn.appClearProgram = Uint8Array.from(Buffer.from(txn.appClearProgram));
try {
txn.appClearProgram = Uint8Array.from(Buffer.from(txn.appClearProgram,'base64'));
}
catch{
message.error = 'Error trying to parse appClearProgram into a Uint8Array value.';
}
}
if('appArgs' in txn){
var tempArgs = [];
txn.appArgs.forEach(element => {
logging.log(element);
tempArgs.push(Uint8Array.from(Buffer.from(element)));
});
txn.appArgs = tempArgs;
try {
var tempArgs = [];
txn.appArgs.forEach(element => {
logging.log(element);
tempArgs.push(Uint8Array.from(Buffer.from(element,'base64')));
});
txn.appArgs = tempArgs;
}
catch{
message.error = 'Error trying to parse appArgs into Uint8Array values.';
}
}
}

try {
let signedTxn = algosdk.signTransaction(txn, recoveredAccount.sk);
let builtTx = buildTransaction(txn);
let signedTxn = {"txID": builtTx.txID().toString(), "blob": builtTx.signTxn(recoveredAccount.sk)};
let b64Obj = Buffer.from(signedTxn.blob).toString('base64');

message.response = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class AssetCreateTx implements IAssetCreateTx {
group?: any = null;
lease?: any = null;
reKeyTo?: any = null;
flatFee?: any = null;
};

///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class AssetDestroyTx implements IAssetDestroyTx {
group?: any = null;
lease?: any = null;
reKeyTo?: any = null;
flatFee?: any = null;
};

///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class AssetConfigTx implements IAssetConfigTx {
group?: any = null;
lease?: any = null;
reKeyTo?: any = null;
flatFee?: any = null;

// Modifications must include one of these
assetTotal?: number = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class AssetFreezeTx implements IAssetFreezeTx{
group?: any = null;
lease?: any = null;
reKeyTo?: any = null;
flatFee?: any = null;
};

///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class ApplTx implements IApplTx {
group?: any = null;
lease?: any = null;
reKeyTo?: any = null;
flatFee?: any = null;

appIndex?: any = null;
appOnComplete?: any = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class AssetAcceptTx implements IAssetAcceptTx {
lease?: any = null;
reKeyTo?: any = null;
amount?: number = null;
flatFee?: any = null;
}

///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class AssetClawbackTx implements IAssetClawbackTx {
lease?: any = null;
reKeyTo?: any = null;
assetRevocationTarget: string = undefined;
flatFee?: any = null;
}

///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class AssetTransferTx implements IAssetTransferTx {
group?: any = null;
lease?: any = null;
reKeyTo?: any = null;
flatFee?: any = null;
}

///
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Validate, ValidationResponse } from "../utils/validator";
import { Validate, ValidationResponse, ValidationStatus } from "../utils/validator";
import { logging } from "@algosigner/common/logging";
import { InvalidTransactionStructure } from "../../errors/validation"

Expand Down Expand Up @@ -63,5 +63,10 @@ export class BaseValidatedTxnWrap {
if(extraFields.length > 0){
throw new InvalidTransactionStructure(`Creation of ${txnType.name} has extra or invalid fields: ${extraFields.toString()}.`)
}

// If we don't have a flatFee or it is falsy and we have a non-zero fee, create a warning.
if(!params['flatFee'] && (params['fee'] && (params['fee'] > 0))){
this.validityObject["flatFee"] = new ValidationResponse({status:ValidationStatus.Warning, info:'The fee is subject to change without flatFee enabled.'});
}
}
}
Loading

0 comments on commit 8c0cfac

Please sign in to comment.