Skip to content

Commit 39a341a

Browse files
committed
feat: present more info on contract call signing
1 parent c42f68c commit 39a341a

File tree

7 files changed

+109
-29
lines changed

7 files changed

+109
-29
lines changed

src/constants/common.ts

+1
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ export const APP_LINK_IOS = 'https://apps.apple.com/us/app/superhero-wallet/id15
297297

298298
export const BUG_REPORT_URL = 'https://spgrrc00ymg.typeform.com/to/Kk3Zyjdr';
299299
export const AGGREGATOR_URL = 'https://superhero.com/';
300+
export const SUPERHERO_CHAT_URL = 'https://chat.superhero.com';
300301
export const CONTACT_EMAIL = '[email protected]';
301302

302303
export const MODAL_ACCOUNT_CREATE = 'account-create';

src/lib/json-big.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const convertValuesToBigNumbers = (value) => {
1717
bn.toJSON = () => bn.toString(10);
1818
return bn;
1919
}
20-
return value;
20+
return value.toString();
2121
};
2222

2323
export default {

src/popup/components/Modals/ConfirmTransactionSign.vue

+86-25
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,35 @@
1313
<template v-else>
1414
<TransactionOverview
1515
:transaction="completeTransaction"
16+
:additional-tag="isAeppChatSuperhero
17+
? $t('modals.confirmTransactionSign.superheroChat')
18+
: null"
1619
/>
20+
<div
21+
v-if="isAeppChatSuperhero || error"
22+
class="subtitle"
23+
:class="{ warning: !!error }"
24+
>
25+
<template v-if="!!error">
26+
{{ $t('modals.confirmTransactionSign.unableToExecute') }}
27+
</template>
28+
<template v-else>
29+
<span class="app-name">{{ $t('modals.confirmTransactionSign.superheroChat') }}</span>
30+
{{ $t('modals.confirmTransactionSign.confirmSigning') }}
31+
</template>
32+
</div>
1733
<DetailsItem
1834
v-if="!!error"
1935
:label="$t('pages.transactionDetails.reason')"
2036
:value="error"
2137
class="reason"
2238
data-cy="reason"
2339
/>
40+
<DetailsItem
41+
v-if="decodedCallData?.functionName"
42+
:label="$t('modals.confirmTransactionSign.functionName')"
43+
:value="decodedCallData.functionName"
44+
/>
2445

2546
<template v-if="(isDex || isDexAllowance) && tokenList.length">
2647
<TransactionDetailsPoolTokenRow
@@ -86,6 +107,16 @@
86107
expandable
87108
:label="$t('transaction.advancedDetails')"
88109
>
110+
<DetailsItem
111+
v-if="decodedCallData?.functionName"
112+
:label="$t('modals.confirmTransactionSign.functionName')"
113+
:value="decodedCallData.functionName"
114+
/>
115+
<DetailsItem
116+
v-if="transactionArguments"
117+
:label="$t('modals.confirmTransactionSign.arguments')"
118+
:value="transactionArguments"
119+
/>
89120
<DetailsItem
90121
v-for="key in filteredTxFields"
91122
:key="key"
@@ -133,6 +164,7 @@ import BigNumber from 'bignumber.js';
133164
import { Encoded, getExecutionCost } from '@aeternity/aepp-sdk';
134165
import { ContractByteArrayEncoder, BytecodeContractCallEncoder } from '@aeternity/aepp-calldata';
135166
167+
import JsonBig from '@/lib/json-big';
136168
import type {
137169
ITokenResolved,
138170
ITransaction,
@@ -142,8 +174,10 @@ import type {
142174
TxFunctionRaw,
143175
} from '@/types';
144176
import { tg } from '@/store/plugins/languages';
177+
import { AeDecodedCallData } from '@/protocols/aeternity/types';
145178
import { RejectedByUserError } from '@/lib/errors';
146179
import {
180+
SUPERHERO_CHAT_URL,
147181
PROTOCOL_AETERNITY,
148182
TX_DIRECTION,
149183
} from '@/constants';
@@ -241,11 +275,16 @@ export default defineComponent({
241275
const loading = ref(false);
242276
const error = ref('');
243277
const verifying = ref(false);
278+
const decodedCallData = ref<AeDecodedCallData | undefined>();
244279
245280
const availableTokens = useState('fungibleTokens', 'availableTokens');
246281
const getTxSymbol = useGetter('getTxSymbol');
247282
const getTxAmountTotal = useGetter('getTxAmountTotal');
248283
284+
const isAeppChatSuperhero = computed(
285+
() => `${popupProps.value?.app?.protocol}//${popupProps.value?.app?.name}` === SUPERHERO_CHAT_URL,
286+
);
287+
249288
const transactionWrapped = computed(
250289
(): Partial<ITransaction> => ({ tx: popupProps.value?.tx as ITx }),
251290
);
@@ -312,6 +351,10 @@ export default defineComponent({
312351
() => txFunction.value && DEX_TRANSACTION_TAGS[txFunction.value] === DEX_PROVIDE_LIQUIDITY,
313352
);
314353
354+
const transactionArguments = computed(() => decodedCallData.value?.args?.length
355+
? JsonBig.stringify(decodedCallData.value.args)
356+
: undefined);
357+
315358
function getTokens(txParams: ITx): ITokenResolved[] {
316359
if (!isDex.value && !isDexAllowance.value) {
317360
return [singleToken.value];
@@ -404,7 +447,7 @@ export default defineComponent({
404447
}
405448
}
406449
407-
async function loadAdditionalDexInfo() {
450+
async function loadAdditionalContractCallInfo() {
408451
if (popupProps.value?.tx?.contractId && popupProps.value.tx.callData) {
409452
try {
410453
loading.value = true;
@@ -420,13 +463,15 @@ export default defineComponent({
420463
421464
const bytecodeContractCallEncoder = new BytecodeContractCallEncoder(bytecode);
422465
423-
const rawTxParams = bytecodeContractCallEncoder.decodeCall(
466+
decodedCallData.value = bytecodeContractCallEncoder.decodeCall(
424467
popupProps.value.tx.callData,
425-
) as any;
468+
) as AeDecodedCallData;
469+
470+
if (!decodedCallData.value) return;
426471
427472
const txParams = {
428-
function: rawTxParams.functionName as TxFunctionRaw,
429-
arguments: rawTxParams.args.map((arg: any) => ({
473+
function: decodedCallData.value.functionName as TxFunctionRaw,
474+
arguments: decodedCallData.value.args.map((arg: any) => ({
430475
type: Array.isArray(arg) ? 'list' : 'any',
431476
value: Array.isArray(arg) ? arg.map((element) => ({ value: element })) : arg,
432477
})) as TxArguments[],
@@ -462,7 +507,7 @@ export default defineComponent({
462507
if (popupProps.value) {
463508
await Promise.all([
464509
verifyTransaction(),
465-
loadAdditionalDexInfo(),
510+
loadAdditionalContractCallInfo(),
466511
]);
467512
} else {
468513
error.value = t('modals.transaction-failed.msg');
@@ -474,37 +519,40 @@ export default defineComponent({
474519
});
475520
476521
return {
477-
AnimatedSpinner,
478522
AE_SYMBOL,
523+
AnimatedSpinner,
479524
PROTOCOL_AETERNITY,
480525
TX_FIELDS_TO_DISPLAY,
526+
cancel,
527+
completeTransaction,
528+
decodedCallData,
481529
error,
482530
executionCost,
483-
verifying,
484-
loading,
485-
showAdvanced,
486-
transactionWrapped,
487-
popupProps,
488531
filteredTxFields,
489-
completeTransaction,
490-
tokenList,
491-
tokenAmount,
492-
tokenSymbol,
493-
totalAmount,
494-
swapDirection,
495-
swapDirectionTranslation,
496-
isSwap,
532+
getLabels,
533+
getTxKeyLabel,
534+
getTxSymbol,
535+
isAeppChatSuperhero,
497536
isDex,
498537
isDexAllowance,
499538
isHash,
539+
isSwap,
500540
isTransactionAex9,
541+
loading,
542+
nameAeFee,
543+
popupProps,
544+
showAdvanced,
545+
swapDirection,
546+
swapDirectionTranslation,
501547
swapTokenAmountData,
502-
getTxSymbol,
548+
tokenAmount,
549+
tokenList,
550+
tokenSymbol,
551+
totalAmount,
552+
transactionArguments,
553+
transactionWrapped,
503554
txAeFee,
504-
nameAeFee,
505-
getLabels,
506-
cancel,
507-
getTxKeyLabel,
555+
verifying,
508556
};
509557
},
510558
});
@@ -523,6 +571,19 @@ export default defineComponent({
523571
height: 56px;
524572
}
525573
574+
.subtitle {
575+
margin: 8px 0;
576+
color: variables.$color-grey-light;
577+
578+
&.warning {
579+
color: variables.$color-warning;
580+
}
581+
582+
.app-name {
583+
color: variables.$color-white;
584+
}
585+
}
586+
526587
.transaction-overview {
527588
margin-bottom: 16px;
528589
}

src/popup/components/TransactionOverview.vue

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
:recipient="preparedTransaction.recipient"
77
:transaction-function="preparedTransaction.function"
88
:transaction="transaction"
9+
:additional-tag="additionalTag"
910
/>
1011
</template>
1112

@@ -29,6 +30,7 @@ import type {
2930
TxFunction,
3031
} from '@/types';
3132
import { TX_DIRECTION } from '@/constants';
33+
import type { AeDecodedCallData } from '@/protocols/aeternity/types';
3234
import { TX_FUNCTIONS } from '@/protocols/aeternity/config';
3335
import {
3436
useAeSdk,
@@ -54,6 +56,7 @@ export default defineComponent({
5456
},
5557
props: {
5658
transaction: { type: Object as PropType<ITransaction>, required: true },
59+
additionalTag: { type: String, default: null },
5760
},
5861
setup(props) {
5962
const store = useStore();
@@ -223,10 +226,10 @@ export default defineComponent({
223226
224227
const bytecodeContractCallEncoder = new BytecodeContractCallEncoder(bytecode);
225228
226-
const txParams = bytecodeContractCallEncoder.decodeCall(calldata) as any;
229+
const txParams = bytecodeContractCallEncoder.decodeCall(calldata) as AeDecodedCallData;
227230
if (!txParams) return undefined;
228231
229-
return txParams.args?.[0];
232+
return txParams.args?.[0] as Encoded.AccountAddress;
230233
}
231234
232235
onMounted(async () => {

src/popup/components/TransactionTagList.vue

+5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export default defineComponent({
4141
props: {
4242
customTitle: { type: String, default: null },
4343
transaction: { type: Object as PropType<ITransaction>, default: null },
44+
additionalTag: { type: String, default: null },
4445
dense: Boolean,
4546
},
4647
setup(props) {
@@ -84,6 +85,10 @@ export default defineComponent({
8485
8586
const arr: string[] = [];
8687
88+
if (props.additionalTag) {
89+
arr.push(props.additionalTag);
90+
}
91+
8792
if (outerTxTag.value === Tag.GaMetaTx) {
8893
arr.push(t('transaction.type.gaMetaTx'));
8994
} else if (outerTxTag.value === Tag.PayingForTx) {

src/popup/locales/en.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,12 @@
288288
"nameFee": "Name fee",
289289
"nameId": "Name ID",
290290
"pointers": "Pointers",
291-
"data-sign": "Data to sign"
291+
"data-sign": "Data to sign",
292+
"functionName": "Function name",
293+
"arguments": "Arguments",
294+
"superheroChat": "Superhero Chat",
295+
"unableToExecute": "This transaction can not be executed.",
296+
"confirmSigning": "would like you to confirm a transaction."
292297
},
293298
"confirm-raw-sign": {
294299
"title": "Sign raw transaction",

src/protocols/aeternity/types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,8 @@ export interface AeTippingContractAddresses {
5050
tippingV1?: Encoded.ContractAddress;
5151
tippingV2?: Encoded.ContractAddress;
5252
}
53+
54+
export interface AeDecodedCallData {
55+
functionName: string;
56+
args: string[];
57+
}

0 commit comments

Comments
 (0)