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

Commit

Permalink
Fix regression affecting Ledger devices caused by #427
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Marcano committed Aug 31, 2022
1 parent 37930d1 commit 5d0f3b1
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 46 deletions.
47 changes: 20 additions & 27 deletions packages/extension/src/background/messaging/internalMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,27 +434,28 @@ export class InternalMethods {
}

public static [JsonRpcMethod.LedgerGetSessionTxn](request: any, sendResponse: Function) {
if (session.txnWrap) {
// The transaction contains source and JSONRPC info, the body.params will be the transaction validation object
sendResponse(session.txnWrap);
if (session.txnRequest && 'body' in session.txnRequest) {
// The session object gets the transaction validation object from the original request
sendResponse(session.txnObject);
} else {
sendResponse({ error: 'Transaction not found in session.' });
}
return true;
}

public static [JsonRpcMethod.LedgerSendTxnResponse](request: any, sendResponse: Function) {
if (session.txnWrap && 'body' in session.txnWrap) {
const txnBuf = Buffer.from(request.body.params.txn, 'base64');
if (session.txnRequest && session.txnObject && request.body?.params?.txn) {
const signedTxn = request.body.params.txn;
const txnBuf = Buffer.from(signedTxn, 'base64');
const decodedTxn = algosdk.decodeSignedTransaction(txnBuf);
const signedTxnEntries = Object.entries(decodedTxn.txn).sort();

// Get the session transaction
const sessTxn = session.txnWrap.body.params.transaction;
const sessTxn = session.txnObject.transaction;

// Set the fee to the estimate we showed on the screen for validation if there is one.
if (session.txnWrap.body.params.estimatedFee) {
sessTxn['fee'] = session.txnWrap.body.params.estimatedFee;
if (session.txnObject.estimatedFee) {
sessTxn['fee'] = session.txnObject.estimatedFee;
}
const sessTxnEntries = Object.entries(sessTxn).sort();

Expand Down Expand Up @@ -485,26 +486,18 @@ export class InternalMethods {
signedTxnEntries['closeRemainderTo'] === sessTxnEntries['closeRemainderTo']
) {
//Check the txnWrap for a dApp response and return the transaction
if (session.txnWrap.source === 'dapp') {
const message = session.txnWrap;

// 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,
};
}
if (session.txnRequest.source === 'dapp') {
const message = session.txnRequest;
message.response = [
{
blob: signedTxn,
},
];

sendResponse({ message: message });
}
// If this is a ui transaction then we need to also submit
else if (session.txnWrap.source === 'ui') {
else if (session.txnRequest.source === 'ui') {
const ledger = getLedgerFromGenesisId(decodedTxn.txn.genesisID);

const algod = this.getAlgod(ledger);
Expand Down Expand Up @@ -533,7 +526,7 @@ export class InternalMethods {
}

// Clear the cached transaction
session.txnWrap.body.params.transaction = undefined;
session.txnRequest.body.params.transaction = undefined;
} else {
sendResponse({ error: 'Transaction not found in session, unable to validate for send.' });
}
Expand All @@ -544,10 +537,10 @@ export class InternalMethods {
// Protected because this should only be called from within the ui or dapp sign methods
protected static [JsonRpcMethod.LedgerSignTransaction](request: any, sendResponse: Function) {
// Access store here here to save the transaction wrap to cache before the site picks it up.
// Explicitly using txnWrap on session instead of auth message for two reasons:
// Explicitly saving txnRequest on session instead of auth message for two reasons:
// 1) So it lives inside background sandbox containment.
// 2) The extension may close before a proper id on the new tab can allow the data to be saved.
session.txnWrap = request.body.params;
session.txnRequest = request;

// Transaction wrap will contain response message if from dApp and structure will be different
const ledger = getLedgerFromGenesisId(request.body.params.transaction.genesisID);
Expand Down
33 changes: 19 additions & 14 deletions packages/extension/src/background/utils/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,40 @@ export default class Session {
private _wallet: any;
private _ledger: any;
private _availableLedgers: any;
private _txnWrap: any;
private _txnRequest: any;

public set wallet(v: any) {
this._wallet = v;
public set wallet(w: any) {
this._wallet = w;
}

public get wallet(): any {
return this._wallet;
}

public set ledger(v: any) {
this._ledger = v;
public set ledger(l: any) {
this._ledger = l;
}

public get ledger(): any {
return this._ledger;
}

public set txnWrap(w: any) {
this._txnWrap = w;
public set txnRequest(r: any) {
this._txnRequest = r;
}

public get txnWrap(): any {
const w = this._txnWrap;
return w;
public get txnRequest(): any {
const r = this._txnRequest;
return r;
}

public set availableLedgers(v: any) {
this._availableLedgers = v;
public get txnObject(): any {
const r = this._txnRequest;
return r?.body?.params;
}

public set availableLedgers(al: any) {
this._availableLedgers = al;
}

public get availableLedgers(): any {
Expand All @@ -46,14 +51,14 @@ export default class Session {
wallet: this._wallet,
ledger: this._ledger,
availableLedgers: this._availableLedgers || [],
txnWrap: this._txnWrap,
txnRequest: this._txnRequest,
};
}

public clearSession(): void {
this._wallet = undefined;
this._ledger = undefined;
this._availableLedgers = undefined;
this._txnWrap = undefined;
this._txnRequest = undefined;
}
}
15 changes: 10 additions & 5 deletions packages/ui/src/components/LedgerDevice/LedgerHardwareSign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,20 @@ const LedgerHardwareSign: FunctionalComponent = () => {
}

if (response && 'txId' in response) {
setTxResponseHeader('Transaction sent:');
setTxResponseHeader('Transaction sent with ID:');
setTxResponseDetail(response['txId']);
setIsComplete(true);
} else {
} else if (response) {
console.log(`response: ${JSON.stringify(response)}`);
setTxResponseHeader('Transaction signed. Result sent to origin tab.');
setTxResponseDetail(JSON.stringify(response));
setIsComplete(true);
} else {
console.log('response not found');
setError('There was a problem signing the transaction, please try again.');
}

setLoading(true);
setLoading(false);
});
});
};
Expand All @@ -111,9 +114,11 @@ const LedgerHardwareSign: FunctionalComponent = () => {
<div class="top-view" style="flex: 1; overflow-y: auto; overflow-x: hidden;">
${isComplete &&
html`
<div class="box">
<div class="mt-2 px-4">
<p id="txResponseHeader" style="font-weight: bold">${txResponseHeader}</p>
<p id="txResponseDetail" style="word-break: break-all;">${txResponseDetail}</p>
<pre style="white-space: break-spaces;" class="mt-2">
<code id="txResponseDetail" style="word-break: break-all;">${txResponseDetail}</code>
</pre>
<p class="my-3">You may now close this site and relaunch AlgoSigner.</p>
</div>
`}
Expand Down

0 comments on commit 5d0f3b1

Please sign in to comment.