Skip to content

Commit

Permalink
Transaction interpretation helpers (#55)
Browse files Browse the repository at this point in the history
* Added transaction interpretation helpers

* Added transaction interpretation helpers

* Added trimUsernameDomain.ts

* Refactor

* 0.0.0-alpha.12

* 0.0.0-alpha.10

* Refactor

* Refactor

* Fix
  • Loading branch information
razvantomegea authored Dec 23, 2024
1 parent 079d116 commit 29e61db
Show file tree
Hide file tree
Showing 61 changed files with 2,170 additions and 7,515 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [[0.0.0-alpha.10](https://github.com/multiversx/mx-sdk-dapp-core/pull/56)] - 2024-12-23

- [Added transactions interpretation helpers](https://github.com/multiversx/mx-sdk-dapp-core/pull/55)
- [Added transaction toasts](https://github.com/multiversx/mx-sdk-dapp-core/pull/53)
- [Added transactions helpers](https://github.com/multiversx/mx-sdk-dapp-core/pull/52)
- [Added transactions tracking](https://github.com/multiversx/mx-sdk-dapp-core/pull/51)
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@multiversx/sdk-dapp-core",
"version": "0.0.0-alpha.11",
"version": "0.0.0-alpha.10",
"main": "out/index.js",
"module": "out/index.js",
"types": "out/index.d.ts",
Expand Down Expand Up @@ -33,13 +33,16 @@
},
"dependencies": {
"@lifeomic/axios-fetch": "3.0.1",
"@multiversx/sdk-core": ">= 13.5.0",
"@multiversx/sdk-dapp-utils": ">= 1.0.2",
"@multiversx/sdk-extension-provider": "4.0.0",
"@multiversx/sdk-hw-provider": "7.0.0",
"@multiversx/sdk-metamask-provider": "1.0.0",
"@multiversx/sdk-native-auth-client": "^1.0.8",
"@multiversx/sdk-opera-provider": "1.0.0-alpha.1",
"@multiversx/sdk-wallet": "4.5.1",
"@multiversx/sdk-wallet-connect-provider": "5.0.1",
"@multiversx/sdk-web-wallet-cross-window-provider": ">= 2.0.4",
"@multiversx/sdk-web-wallet-iframe-provider": "2.0.1",
"@multiversx/sdk-web-wallet-provider": "3.2.1",
"isomorphic-fetch": "3.0.0",
Expand All @@ -64,9 +67,6 @@
},
"devDependencies": {
"@eslint/js": "9.15.0",
"@multiversx/sdk-core": ">= 13.5.0",
"@multiversx/sdk-dapp-utils": ">= 1.0.2",
"@multiversx/sdk-web-wallet-cross-window-provider": ">= 2.0.4",
"@swc/core": "^1.4.17",
"@swc/jest": "^0.2.36",
"@types/jest": "29.5.13",
Expand Down
4 changes: 4 additions & 0 deletions src/apiCalls/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export * from './account';
export * from './configuration';
export * from './endpoints';
export * from './tokens';
export * from './utils';
export * from './websocket';
60 changes: 60 additions & 0 deletions src/apiCalls/tokens/getTokenDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { NFTS_ENDPOINT, TOKENS_ENDPOINT } from 'apiCalls/endpoints';
import { axiosInstance } from 'apiCalls/utils/axiosInstance';
import { networkSelector } from 'store/selectors';
import { getState } from 'store/store';
import { TokenOptionType, TokenInfoResponse } from 'types/tokens.types';
import { getIdentifierType } from 'utils/validation/getIdentifierType';

export async function getTokenDetails({
tokenId
}: {
tokenId: string;
}): Promise<TokenOptionType> {
const network = networkSelector(getState());
const { isNft } = getIdentifierType(tokenId);

const tokenIdentifier = tokenId;
const tokenEndpoint = isNft ? NFTS_ENDPOINT : TOKENS_ENDPOINT;

if (!tokenIdentifier) {
return {
tokenDecimals: Number(network.decimals),
tokenLabel: '',
tokenAvatar: ''
};
}

try {
const { data: selectedToken } = await axiosInstance.get<TokenInfoResponse>(
`${network.apiAddress}/${tokenEndpoint}/${tokenIdentifier}`
);

const tokenDecimals = selectedToken
? selectedToken?.decimals
: Number(network.decimals);
const tokenLabel = selectedToken ? selectedToken?.name : '';
const tokenAvatar = selectedToken
? selectedToken?.assets?.svgUrl ?? selectedToken?.media?.[0]?.thumbnailUrl
: '';

return {
tokenDecimals: tokenDecimals,
tokenLabel,
type: selectedToken?.type,
tokenAvatar,
identifier: selectedToken?.identifier,
assets: selectedToken?.assets,
esdtPrice: selectedToken?.price,
ticker: selectedToken?.ticker,
name: selectedToken?.name
};
} catch (error: any) {
return {
error: `Error fetching token ${tokenIdentifier}: ${error.toString()}`,
tokenDecimals: Number(network.decimals),
tokenLabel: '',
tokenAvatar: '',
identifier: tokenIdentifier
};
}
}
1 change: 1 addition & 0 deletions src/apiCalls/tokens/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './getTokenDetails';
1 change: 1 addition & 0 deletions src/constants/mvx.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export const VERSION = 1;
export const LEDGER_CONTRACT_DATA_ENABLED_VALUE = 1;
export const METACHAIN_SHARD_ID = 4294967295;
export const ALL_SHARDS_SHARD_ID = 4294967280;
export const REFUNDED_GAS = 'refundedGas';
2 changes: 1 addition & 1 deletion src/constants/webWalletProvider.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ export {
WALLET_PROVIDER_SIGN_MESSAGE_URL,
WALLET_PROVIDER_CALLBACK_PARAM,
WALLET_PROVIDER_CALLBACK_PARAM_TX_SIGNED
} from '@multiversx/sdk-web-wallet-provider';
} from '@multiversx/sdk-web-wallet-provider';
13 changes: 9 additions & 4 deletions src/core/providers/types/providerFactory.types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { IDAppProviderBase } from '@multiversx/sdk-dapp-utils';

// @ts-ignore
export interface IProvider<T extends ProviderTypeEnum = ProviderTypeEnum> extends IDAppProviderBase {
export interface IProvider<T extends ProviderTypeEnum = ProviderTypeEnum>
extends IDAppProviderBase {
init: () => Promise<boolean>;
login: (options?: { callbackUrl?: string; token?: string }) => Promise<{
address: string;
Expand Down Expand Up @@ -39,14 +40,18 @@ export enum ProviderTypeEnum {
opera = 'opera',
metamask = 'metamask',
passkey = 'passkey',
none = '',
none = ''
}

export interface IProviderFactory<T extends ProviderTypeEnum = ProviderTypeEnum> {
export interface IProviderFactory<
T extends ProviderTypeEnum = ProviderTypeEnum
> {
type: T[keyof T];
}

export interface ICustomProvider<T extends ProviderTypeEnum = ProviderTypeEnum> {
export interface ICustomProvider<
T extends ProviderTypeEnum = ProviderTypeEnum
> {
name: string;
type: T[keyof T];
icon: string;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/sdkDappUtils.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { formatAmount } from '@multiversx/sdk-dapp-utils/out/helpers/formatAmount';
export { formatAmount } from '@multiversx/sdk-dapp-utils/out/helpers';
44 changes: 44 additions & 0 deletions src/types/tokens.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,47 @@ export interface NftType {
}[];
scamInfo?: ScamInfoType;
}

export interface TokenAssets {
description: string;
status: string;
svgUrl: string;
website?: string;
pngUrl?: string;
social?: any;
extraTokens?: string[];
lockedAccounts?: { [key: string]: string };
}

export interface TokenMediaType {
url?: string;
originalUrl?: string;
thumbnailUrl?: string;
fileType?: string;
fileSize?: number;
}

export interface TokenOptionType {
tokenLabel: string;
tokenDecimals: number;
tokenAvatar: string;
assets?: TokenAssets;
type?: NftEnumType;
error?: string;
esdtPrice?: number;
ticker?: string;
identifier?: string;
name?: string;
isLoading?: boolean;
}

export interface TokenInfoResponse {
identifier: string;
name: string;
ticker: string;
decimals: number;
type?: NftEnumType;
assets: TokenAssets;
media?: TokenMediaType[];
price: number;
}
7 changes: 7 additions & 0 deletions src/types/transactions.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,10 @@ export interface SmartContractResult {
miniBlockHash: string;
returnMessage: string;
}

export enum TransactionDirectionEnum {
SELF = 'Self',
INTERNAL = 'Internal',
IN = 'In',
OUT = 'Out'
}
1 change: 1 addition & 0 deletions src/utils/account/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './fetchAccount';
export * from './refreshAccount';
export * from './trimUsernameDomain';
12 changes: 12 additions & 0 deletions src/utils/account/trimUsernameDomain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const trimUsernameDomain = (username?: string) => {
if (!username) {
return;
}

const elrondSuffixExists = username.lastIndexOf('.elrond') > 0;
const trimmedPartBeforeLastDot = elrondSuffixExists
? username.substring(0, username.lastIndexOf('.'))
: username;

return trimmedPartBeforeLastDot;
};
File renamed without changes.
33 changes: 33 additions & 0 deletions src/utils/operations/tests/timeRemaining.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { timeRemaining } from '../timeRemaining';

describe('timeRemaining tests - short time format', () => {
const entries: [number, string][] = [
[1076, '17 min'],
[3976, '1 hr'],
[5286, '1 hr']
];

for (let i = 0; i < entries.length; i++) {
const [input, output] = entries[i];
test(`parse ${input} -> ${output}`, () => {
const result = timeRemaining(input);
expect(result).toStrictEqual(output);
});
}
});

describe('timeRemaining tests - long time format', () => {
const entries: [number, string][] = [
[1076, '17 min 56 sec'],
[3976, '1 hr 6 min'],
[5286, '1 hr 28 min']
];

for (let i = 0; i < entries.length; i++) {
const [input, output] = entries[i];
test(`parse ${input} -> ${output}`, () => {
const result = timeRemaining(input, false);
expect(result).toStrictEqual(output);
});
}
});
88 changes: 88 additions & 0 deletions src/utils/operations/timeRemaining.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
export function getRemainingTime(ms: number) {
const days = Math.floor(ms / (24 * 60 * 60 * 1000));
const daysms = ms % (24 * 60 * 60 * 1000);
const hrs = Math.floor(daysms / (60 * 60 * 1000));
const hrsms = daysms % (60 * 60 * 1000);
const mins = Math.floor(hrsms / (60 * 1000));
const minsms = hrsms % (60 * 1000);
const secs = Math.floor(minsms / 1000);

let secsString = secs + ' sec';
let minsString = mins + ' min';
let hrsString = hrs + ' hr';
let daysString = days + ' day';

if (secs > 1) {
secsString = secs + ' sec';
}
if (mins > 1) {
minsString = mins + ' min';
}
if (hrs > 1) {
hrsString = hrs + ' hrs';
}
if (days > 1) {
daysString = days + ' days';
}

if (days >= 1) {
return daysString + ' ' + hrsString;
}
if (hrs >= 1) {
const minutesString = mins === 0 ? '' : ' ' + minsString;
return hrsString + minutesString;
}
if (mins >= 1) {
const secString = secs === 0 ? '' : ' ' + secsString;
return minsString + secString;
}

return secsString;
}

function getShortDateTimeFormat(datetime: string) {
const parts = datetime.split(' ');
if (parts.length > 1) {
return `${parts[0]} ${parts[1]}`;
}
return datetime;
}

const getUTCDateNow = (date = new Date(), extendedSeconds = 0) =>
Date.UTC(
date.getUTCFullYear(),
date.getUTCMonth(),
date.getUTCDate(),
date.getUTCHours(),
date.getUTCMinutes(),
date.getUTCSeconds() + extendedSeconds,
date.getUTCMilliseconds()
);

function getUTCdiffInMs(duration: number) {
const date = new Date();
const startDate = getUTCDateNow(date);
const endDate = getUTCDateNow(date, duration);
const diffInMs = Math.max(endDate - startDate, 0);
return diffInMs;
}

export function timeRemaining(duration: number, short = true) {
const diffInMs = getUTCdiffInMs(duration);
const remaining = getRemainingTime(diffInMs);
return short ? getShortDateTimeFormat(remaining) : remaining;
}

function getDifferenceInMs(timestamp: number) {
const dateNow = new Date().getTime();
const difference = dateNow - timestamp;
const diffInMs = Math.max(difference, 0);
return diffInMs;
}

export function timeAgo(timestamp: number, short = true) {
const diffInMs = getDifferenceInMs(timestamp);
const remaining = getRemainingTime(diffInMs);

return short ? getShortDateTimeFormat(remaining) : remaining;
}
Loading

0 comments on commit 29e61db

Please sign in to comment.