Skip to content

Commit

Permalink
Rework sign-staking request to take any raw staking transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
sisou committed Dec 12, 2023
1 parent dfafa5e commit ea7c91d
Show file tree
Hide file tree
Showing 13 changed files with 119 additions and 130 deletions.
16 changes: 5 additions & 11 deletions client/PublicRequestTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,10 @@ export interface SignTransactionRequest extends BasicRequest {
validityStartHeight: number; // FIXME To be made optional when hub has its own network
}

export interface SignStakingRequest extends SignTransactionRequest {
type: number;

// For createStaker and updateStaker transactions
delegation?: string;

// For updateStaker transactions
reactivateAllStake?: boolean;

// For inactivateStake transactions
newInactiveBalance?: number;
export interface SignStakingRequest extends BasicRequest {
senderLabel?: string;
recipientLabel?: string;
transaction: Uint8Array;
}

export interface NimiqCheckoutRequest extends BasicRequest {
Expand Down Expand Up @@ -225,6 +218,7 @@ export interface MultiCurrencyCheckoutRequest extends BasicRequest {
export type CheckoutRequest = NimiqCheckoutRequest | MultiCurrencyCheckoutRequest;

export interface SignedTransaction {
transaction: Uint8Array;
serializedTx: string; // HEX
hash: string; // HEX

Expand Down
10 changes: 5 additions & 5 deletions client/dist/src/PublicRequestTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,10 @@ export interface SignTransactionRequest extends BasicRequest {
flags?: number;
validityStartHeight: number;
}
export interface SignStakingRequest extends SignTransactionRequest {
type: number;
delegation?: string;
reactivateAllStake?: boolean;
newInactiveBalance?: number;
export interface SignStakingRequest extends BasicRequest {
senderLabel?: string;
recipientLabel?: string;
transaction: Uint8Array;
}
export interface NimiqCheckoutRequest extends BasicRequest {
version?: 1;
Expand Down Expand Up @@ -175,6 +174,7 @@ export interface MultiCurrencyCheckoutRequest extends BasicRequest {
}
export declare type CheckoutRequest = NimiqCheckoutRequest | MultiCurrencyCheckoutRequest;
export interface SignedTransaction {
transaction: Uint8Array;
serializedTx: string;
hash: string;
raw: {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@nimiq/electrum-client": "https://github.com/nimiq/electrum-client#build",
"@nimiq/fastspot-api": "^1.7.0",
"@nimiq/iqons": "^1.5.2",
"@nimiq/keyguard-client": "https://gitpkg.vercel.app/nimiq/keyguard?scripts.postinstall=cd%20client%20%26%26%20.%2Fbuild-gitpkg.sh&fb889616bb9221792a6cb2b0194a33cb0835da96",
"@nimiq/keyguard-client": "https://gitpkg.vercel.app/nimiq/keyguard?scripts.postinstall=cd%20client%20%26%26%20.%2Fbuild-gitpkg.sh&2bac12200d370a4c2a64684597ae9b726a3d83f9",
"@nimiq/ledger-api": "^2.3.0",
"@nimiq/network-client": "^0.6.2",
"@nimiq/oasis-api": "^1.1.1",
Expand Down
1 change: 1 addition & 0 deletions src/components/Network.vue
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class Network extends Vue {
: (() => { throw new Error('Unsupported transaction proof'); })();
const result: SignedTransaction = {
transaction: tx.serialize(),
serializedTx: Nimiq.BufferUtils.toHex(tx.serialize()),
hash: tx.hash().toHex(),
Expand Down
22 changes: 11 additions & 11 deletions src/i18n/en.po
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ msgid "Atomic swaps require two BTC transactions."
msgstr ""

#: src/views/CashlinkManage.vue:192
#: src/views/CheckoutTransmission.vue:77
msgid "Awaiting receipt confirmation..."
msgstr ""

Expand Down Expand Up @@ -399,7 +398,7 @@ msgid "Connecting to Keyguard..."
msgstr ""

#: src/views/CashlinkManage.vue:133
#: src/views/CheckoutTransmission.vue:36
#: src/views/CheckoutTransmission.vue:42
#: src/views/LoginSuccess.vue:44
msgid "Connecting to network..."
msgstr ""
Expand All @@ -411,7 +410,7 @@ msgstr ""
#: src/components/CheckoutCardNimiq.vue:283
#: src/components/CheckoutCardNimiq.vue:288
#: src/views/CashlinkManage.vue:186
#: src/views/CheckoutTransmission.vue:71
#: src/views/CheckoutTransmission.vue:120
msgid "Contacting seed nodes..."
msgstr ""

Expand Down Expand Up @@ -803,7 +802,7 @@ msgstr ""
msgid "Payment successful"
msgstr ""

#: src/views/CheckoutTransmission.vue:82
#: src/views/CheckoutTransmission.vue:128
msgid "Payment successful."
msgstr ""

Expand Down Expand Up @@ -843,7 +842,7 @@ msgstr ""
msgid "Preparing Swap"
msgstr ""

#: src/views/CheckoutTransmission.vue:84
#: src/views/CheckoutTransmission.vue:130
msgid "Processing your payment"
msgstr ""

Expand Down Expand Up @@ -926,7 +925,7 @@ msgid "Sending Transaction"
msgstr ""

#: src/views/CashlinkManage.vue:190
#: src/views/CheckoutTransmission.vue:75
#: src/views/CheckoutTransmission.vue:122
msgid "Sending transaction..."
msgstr ""

Expand All @@ -951,7 +950,7 @@ msgid "Single Accounts"
msgstr ""

#: src/views/CashlinkManage.vue:228
#: src/views/CheckoutTransmission.vue:83
#: src/views/CheckoutTransmission.vue:129
msgid "Something went wrong"
msgstr ""

Expand All @@ -967,7 +966,8 @@ msgstr ""
msgid "Speed up your transaction"
msgstr ""

#: src/views/SignStaking.vue:38
#: src/views/SignStaking.vue:41
#: src/views/SignStaking.vue:57
msgid "Staking Contract"
msgstr ""

Expand Down Expand Up @@ -1003,7 +1003,7 @@ msgstr ""
#: src/components/CheckoutCardNimiq.vue:290
#: src/views/AddVestingContract.vue:11
#: src/views/CashlinkManage.vue:188
#: src/views/CheckoutTransmission.vue:73
#: src/views/CheckoutTransmission.vue:121
msgid "Syncing consensus..."
msgstr ""

Expand Down Expand Up @@ -1115,12 +1115,12 @@ msgid "Total fees"
msgstr ""

#: src/views/CashlinkManage.vue:211
#: src/views/CheckoutTransmission.vue:61
#: src/views/CheckoutTransmission.vue:111
msgid "Transaction could not be relayed"
msgstr ""

#: src/views/CashlinkManage.vue:209
#: src/views/CheckoutTransmission.vue:59
#: src/views/CheckoutTransmission.vue:109
msgid "Transaction is expired"
msgstr ""

Expand Down
48 changes: 30 additions & 18 deletions src/lib/RequestParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ export class RequestParser {

switch (requestType) {
case RequestType.SIGN_TRANSACTION:
case RequestType.SIGN_STAKING:
const signTransactionRequest = request as SignTransactionRequest;

if (!signTransactionRequest.value) throw new Error('value is required');
Expand All @@ -81,14 +80,25 @@ export class RequestParser {
: signTransactionRequest.extraData || new Uint8Array(0),
flags: signTransactionRequest.flags || Nimiq.Transaction.Flag.NONE,
validityStartHeight: signTransactionRequest.validityStartHeight,

...(requestType === RequestType.SIGN_STAKING ? {
type: (signTransactionRequest as any as SignStakingRequest).type,
delegation: (signTransactionRequest as any as SignStakingRequest).delegation,
reactivateAllStake: (signTransactionRequest as any as SignStakingRequest).reactivateAllStake,
newInactiveBalance: (signTransactionRequest as any as SignStakingRequest).newInactiveBalance,
} : {}),
} as ParsedSignTransactionRequest;
case RequestType.SIGN_STAKING:
const signStakingRequest = request as SignStakingRequest;

// const Albatross = await window.loadAlbatross();
// const transaction = Albatross.Transaction.fromAny(
// Nimiq.BufferUtils.toHex(signStakingRequest.transaction),
// );

if (!(signStakingRequest.transaction instanceof Uint8Array)) {
throw new Error('transaction must be a Uint8Array');
}

return {
senderLabel: signStakingRequest.senderLabel,
recipientLabel: signStakingRequest.recipientLabel,
// transaction: transaction.toPlain(),
transaction: signStakingRequest.transaction,
} as ParsedSignStakingRequest;
case RequestType.CHECKOUT:
const checkoutRequest = request as CheckoutRequest;

Expand Down Expand Up @@ -707,7 +717,6 @@ export class RequestParser {
: RpcRequest | null {
switch (request.kind) {
case RequestType.SIGN_TRANSACTION:
case RequestType.SIGN_STAKING:
const signTransactionRequest = request as ParsedSignTransactionRequest;
return {
appName: signTransactionRequest.appName,
Expand All @@ -723,16 +732,19 @@ export class RequestParser {
extraData: signTransactionRequest.data,
flags: signTransactionRequest.flags,
validityStartHeight: signTransactionRequest.validityStartHeight,

...(request.kind === RequestType.SIGN_STAKING ? {
type: (signTransactionRequest as any as ParsedSignStakingRequest).type,
delegation: (signTransactionRequest as any as ParsedSignStakingRequest).delegation,
reactivateAllStake: (signTransactionRequest as any as ParsedSignStakingRequest)
.reactivateAllStake,
newInactiveBalance: (signTransactionRequest as any as ParsedSignStakingRequest)
.newInactiveBalance,
} : {}),
} as SignTransactionRequest;
case RequestType.SIGN_STAKING:
const signStakingRequest = request as ParsedSignStakingRequest;

// const Albatross = await window.loadAlbatross();
// const transaction = Albatross.Transaction.fromPlain(signStakingRequest.transaction);

return {
senderLabel: signStakingRequest.senderLabel,
recipientLabel: signStakingRequest.recipientLabel,
// transaction: transaction.serialize(),
transaction: signStakingRequest.transaction,
} as SignStakingRequest;
case RequestType.CREATE_CASHLINK:
const createCashlinkRequest = request as ParsedCreateCashlinkRequest;
// Note that there is no need to export autoTruncateMessage as the message already got truncated
Expand Down
11 changes: 6 additions & 5 deletions src/lib/RequestTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { ParsedEtherSpecifics, ParsedEtherDirectPaymentOptions } from './pa
import type { ParsedBitcoinSpecifics, ParsedBitcoinDirectPaymentOptions } from './paymentOptions/BitcoinPaymentOptions';
import type { SwapAsset } from '@nimiq/fastspot-api';
import type { FiatApiSupportedFiatCurrency } from '@nimiq/utils';
// import type { PlainTransaction as AlbatrossPlainTransaction } from '@nimiq/albatross-wasm';

export interface ParsedBasicRequest {
kind: RequestType;
Expand Down Expand Up @@ -51,11 +52,11 @@ export interface ParsedSignTransactionRequest extends ParsedBasicRequest {
validityStartHeight: number; // FIXME To be made optional when hub has its own network
}

export interface ParsedSignStakingRequest extends ParsedSignTransactionRequest {
type: number;
delegation?: string;
reactivateAllStake?: boolean;
newInactiveBalance?: number;
export interface ParsedSignStakingRequest extends ParsedBasicRequest {
senderLabel?: string;
recipientLabel?: string;
// transaction: AlbatrossPlainTransaction;
transaction: Uint8Array;
}

export type ParsedProtocolSpecificsForCurrency<C extends Currency> =
Expand Down
26 changes: 18 additions & 8 deletions src/lib/RpcApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,17 +318,27 @@ export default class RpcApi {
accountRequired = true;
account = await WalletStore.Instance.get((request as ParsedSimpleRequest).walletId);
errorMsg = 'AccountId not found';
} else if (requestType === RequestType.SIGN_TRANSACTION || requestType === RequestType.SIGN_STAKING) {
} else if (requestType === RequestType.SIGN_TRANSACTION) {
accountRequired = true;
const parsedSignTransactionRequest = request as ParsedSignTransactionRequest;
const isUnstaking = requestType === RequestType.SIGN_STAKING
&& (request as ParsedSignStakingRequest).type === StakingTransactionType.UNSTAKE;
const address = isUnstaking
? parsedSignTransactionRequest.recipient
: parsedSignTransactionRequest.sender instanceof Nimiq.Address
? parsedSignTransactionRequest.sender
: parsedSignTransactionRequest.sender.address;
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 = false;

// TODO
// The RequestParser is not async, so we cannot load and parse the transation from its
// Uint8Array representation there, so the parsed request cannot contain the plain transaction,
// and we have to do the parsing and validation in SignStaking.vue instead.

// const parsedSignStakingRequest = request as ParsedSignStakingRequest;
// // Only support signing staking transactions by the tx's sender or recipient
// const address = parsedSignStakingRequest.transaction.senderType === 'staking'
// ? parsedSignStakingRequest.transaction.recipient
// : parsedSignStakingRequest.transaction.sender;
// account = this._store.getters.findWalletByAddress(address, true);
} else if (requestType === RequestType.SIGN_MESSAGE) {
accountRequired = false; // Sign message allows user to select an account
const address = (request as ParsedSignMessageRequest).signer;
Expand Down
1 change: 1 addition & 0 deletions src/views/CheckoutTransmission.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export default class CheckoutTransmission extends Vue {
const plain = tx.toPlain();
const result: SignedTransaction = {
transaction: this.keyguardResult.serializedTx,
serializedTx: hex,
hash: plain.transactionHash,
raw: {
Expand Down
Loading

0 comments on commit ea7c91d

Please sign in to comment.