Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/PublicRequestTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export interface ChooseAddressResult extends Address {
}

export interface SignTransactionRequest extends BasicRequest {
sender: string;
sender?: string;
recipient: string;
recipientType?: Nimiq.AccountType;
recipientLabel?: string;
Expand Down
34 changes: 27 additions & 7 deletions demos/Demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class Demo {
});

document.querySelector('button#sign-transaction')!.addEventListener('click', async () => {
const txRequest = generateSignTransactionRequest();
const txRequest = generateSignTransactionRequest(true);
try {
const result = await demo.client.signTransaction(
new Promise<SignTransactionRequest>((resolve) => {
Expand All @@ -199,6 +199,23 @@ class Demo {
}
});

document.querySelector('button#sign-transaction-without-sender')!.addEventListener('click', async () => {
const txRequest = generateSignTransactionRequest(false);
try {
const result = await demo.client.signTransaction(
new Promise<SignTransactionRequest>((resolve) => {
window.setTimeout(() => resolve(txRequest), 2000);
}),
demo._defaultBehavior,
);
console.log('Result', result);
document.querySelector('#result')!.textContent = 'TX signed';
} catch (e) {
console.error(e);
document.querySelector('#result')!.textContent = `Error: ${e.message || e}`;
}
});

document.querySelector('button#onboard')!.addEventListener('click', async () => {
try {
const result = await demo.client.onboard({ appName: 'Hub Demos' }, demo._defaultBehavior);
Expand Down Expand Up @@ -235,13 +252,16 @@ class Demo {
}
});

function generateSignTransactionRequest(): SignTransactionRequest {
const $radio = document.querySelector('input[name="address"]:checked');
if (!$radio) {
alert('You have no account to send a tx from, create an account first (signup)');
throw new Error('No account found');
function generateSignTransactionRequest(withSender: boolean): SignTransactionRequest {
let sender: string | undefined;
if (withSender) {
const $radio = document.querySelector('input[name="address"]:checked');
if (!$radio) {
alert('You have no account to send a tx from, create an account first (signup)');
throw new Error('No account found');
}
sender = ($radio as HTMLElement).dataset.address!;
}
const sender = ($radio as HTMLElement).dataset.address!;
const value = parseInt((document.querySelector('#value') as HTMLInputElement).value, 10) || 1337;
const fee = parseInt((document.querySelector('#fee') as HTMLInputElement).value, 10) || 0;
const txData = (document.querySelector('#data') as HTMLInputElement).value || '';
Expand Down
1 change: 1 addition & 0 deletions demos/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ <h2>Transactions</h2>
<br><button id="checkout" disabled>Checkout</button>
<br><button id="multi-checkout" disabled>Multi Checkout</button>
<br><button id="sign-transaction" disabled>Sign Transaction</button>
<br><button id="sign-transaction-without-sender" disabled>Sign Transaction without Sender</button>
</div>

<div class="request">
Expand Down
1 change: 0 additions & 1 deletion src/components/CheckoutCardNimiq.vue
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,6 @@ class CheckoutCardNimiq
}

private get hasEligibleAddress(): boolean {

const recipientAddress = this.paymentOptions.protocolSpecific.recipient
? this.paymentOptions.protocolSpecific.recipient.toUserFriendlyAddress()
: '';
Expand Down
15 changes: 10 additions & 5 deletions src/lib/RequestParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ export class RequestParser {
return {
kind: requestType,
appName: signTransactionRequest.appName,
sender: Nimiq.Address.fromString(signTransactionRequest.sender),
sender: signTransactionRequest.sender
? Nimiq.Address.fromString(signTransactionRequest.sender)
: undefined,
recipient: Nimiq.Address.fromString(signTransactionRequest.recipient),
recipientType: signTransactionRequest.recipientType || Nimiq.AccountType.Basic,
recipientLabel: signTransactionRequest.recipientLabel,
Expand Down Expand Up @@ -875,10 +877,13 @@ export class RequestParser {
const signTransactionRequest = request as ParsedSignTransactionRequest;
return {
appName: signTransactionRequest.appName,
sender: signTransactionRequest.sender instanceof Nimiq.Address
? signTransactionRequest.sender.toUserFriendlyAddress()
// Note: additional sender information is lost and does not survive reloads, see RequestTypes.ts
: signTransactionRequest.sender.address.toUserFriendlyAddress(),
sender: signTransactionRequest.sender
? signTransactionRequest.sender instanceof Nimiq.Address
? signTransactionRequest.sender.toUserFriendlyAddress()
// Note: additional sender information is lost and does not survive reloads,
// see RequestTypes.ts
: signTransactionRequest.sender.address.toUserFriendlyAddress()
: undefined,
recipient: signTransactionRequest.recipient.toUserFriendlyAddress(),
recipientType: signTransactionRequest.recipientType,
recipientLabel: signTransactionRequest.recipientLabel,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/RequestTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export interface ParsedSignTransactionRequest extends ParsedBasicRequest {
// The sender object is currently only for internal use in RefundSwapLedger and can not be set in public request.
// Note that the object does not get exported to the history state in RpcApi and therefore does not survive reloads.
// However, the RefundSwapLedger handler is built in a way that it starts over on reloads to avoid the problem.
sender: Nimiq.Address | {
sender?: Nimiq.Address | {
address: Nimiq.Address,
label?: string,
walletLabel?: string,
Expand Down
14 changes: 8 additions & 6 deletions src/lib/RpcApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { ERROR_CANCELED, StakingTransactionType, WalletType } from './Constants'
import { includesOrigin } from '@/lib/Helpers';
import Config from 'config';
import { setHistoryStorage, getHistoryStorage } from '@/lib/Helpers';
import { WalletInfo } from './WalletInfo';
import type { WalletInfo } from './WalletInfo';

export default class RpcApi {
public static PERMISSIONED_REQUESTS: RequestType[] = [
Expand Down Expand Up @@ -332,12 +332,14 @@ export default class RpcApi {
account = await WalletStore.Instance.get((request as ParsedSimpleRequest).walletId);
errorMsg = 'AccountId not found';
} else if (requestType === RequestType.SIGN_TRANSACTION) {
accountRequired = true;
accountRequired = false;
const parsedSignTransactionRequest = request as ParsedSignTransactionRequest;
const address = parsedSignTransactionRequest.sender instanceof Nimiq.Address
? parsedSignTransactionRequest.sender
: parsedSignTransactionRequest.sender.address;
account = this._store.getters.findWalletByAddress(address.toUserFriendlyAddress(), true);
if (parsedSignTransactionRequest.sender) {
const address = parsedSignTransactionRequest.sender instanceof Nimiq.Address
? parsedSignTransactionRequest.sender
: parsedSignTransactionRequest.sender.address;
account = this._store.getters.findWalletByAddress(address.toUserFriendlyAddress(), true);
}
} else if (requestType === RequestType.SIGN_STAKING) {
accountRequired = true;
// Only support signing staking transactions by the tx's sender or recipient. Note that sending to or
Expand Down
11 changes: 7 additions & 4 deletions src/views/ErrorHandler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,13 @@ export default class ErrorHandler extends Vue {
// The wallet can be found by the (optional) sender/signer address in the Hub request
const messageSigner = (this.request as ParsedSignMessageRequest).signer;
const transactionSender = (this.request as ParsedSignTransactionRequest).sender;
const address = messageSigner || (transactionSender instanceof Nimiq.Address
? transactionSender
: transactionSender.address);
return this.findWalletByAddress(address.toUserFriendlyAddress(), true);
const maybeAddress = messageSigner || transactionSender;
if (maybeAddress) {
const address = maybeAddress instanceof Nimiq.Address
? maybeAddress
: maybeAddress.address;
return this.findWalletByAddress(address.toUserFriendlyAddress(), true);
}
} else if (this.request.kind === RequestType.CHECKOUT
|| this.request.kind === RequestType.SIGN_MESSAGE) {
// The keyId of the selected address is in the keyguardRequest
Expand Down
4 changes: 4 additions & 0 deletions src/views/RefundSwapLedger.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ export default class RefundSwapLedger extends RefundSwap {

const request = this.request as ParsedSignTransactionRequest;
const { sender: senderInfo, recipient, value, fee, data, validityStartHeight } = request;
if (!senderInfo) {
this.$rpc.reject(new Error('Ledger Swap Refunding expects a sender in the request.'));
return;
}
const sender = senderInfo instanceof Nimiq.Address ? senderInfo : senderInfo.address;
// existence guaranteed as already checked previously in RefundSwap
const ledgerAccount = this.findWalletByAddress(recipient.toUserFriendlyAddress(), true)!;
Expand Down
Loading
Loading