From c50c65d3069ef7e427218c25d20a6758d55bb517 Mon Sep 17 00:00:00 2001 From: Sam Ruberti Date: Wed, 14 Jun 2023 18:05:13 -0400 Subject: [PATCH] feat: add timestamp hooks and core funcs (#91) --- packages/useink/package.json | 2 +- .../core/substrate/timestamp/getTimestamp.ts | 5 ----- .../substrate/timestamp/getTimestampDate.ts | 12 ++++++++++++ .../substrate/timestamp/getTimestampNow.ts | 19 +++++++++++-------- .../substrate/timestamp/getTimestampQuery.ts | 5 +++++ .../src/core/substrate/timestamp/index.ts | 3 ++- .../useink/src/react/hooks/helpers/index.ts | 1 + .../react/hooks/helpers/useUnixMilliToDate.ts | 7 +++++++ packages/useink/src/react/hooks/index.ts | 1 + .../react/hooks/substrate/balance/index.ts | 1 + .../substrate/{ => balance}/useBalance.ts | 12 ++++++------ .../useink/src/react/hooks/substrate/index.ts | 3 ++- .../react/hooks/substrate/timestamp/index.ts | 3 +++ .../substrate/timestamp/useTimestampDate.ts | 9 +++++++++ .../substrate/timestamp/useTimestampNow.ts | 18 ++++++++++++++++++ .../substrate/timestamp/useTimestampQuery.ts | 19 +++++++++++++++++++ packages/useink/src/utils/helpers/index.ts | 1 + .../src/utils/helpers/unixMilliToDate.ts | 4 ++++ .../src/components/pg-home/HomePage.tsx | 18 ++++++++++++++++++ words.txt | 1 + 20 files changed, 122 insertions(+), 22 deletions(-) delete mode 100644 packages/useink/src/core/substrate/timestamp/getTimestamp.ts create mode 100644 packages/useink/src/core/substrate/timestamp/getTimestampDate.ts create mode 100644 packages/useink/src/core/substrate/timestamp/getTimestampQuery.ts create mode 100644 packages/useink/src/react/hooks/helpers/index.ts create mode 100644 packages/useink/src/react/hooks/helpers/useUnixMilliToDate.ts create mode 100644 packages/useink/src/react/hooks/substrate/balance/index.ts rename packages/useink/src/react/hooks/substrate/{ => balance}/useBalance.ts (65%) create mode 100644 packages/useink/src/react/hooks/substrate/timestamp/index.ts create mode 100644 packages/useink/src/react/hooks/substrate/timestamp/useTimestampDate.ts create mode 100644 packages/useink/src/react/hooks/substrate/timestamp/useTimestampNow.ts create mode 100644 packages/useink/src/react/hooks/substrate/timestamp/useTimestampQuery.ts create mode 100644 packages/useink/src/utils/helpers/unixMilliToDate.ts diff --git a/packages/useink/package.json b/packages/useink/package.json index 21ab217..91af226 100644 --- a/packages/useink/package.json +++ b/packages/useink/package.json @@ -12,7 +12,7 @@ "React", "hooks" ], - "version": "1.7.5", + "version": "1.8.0", "main": "dist/index.js", "module": "dist/index.mjs", "description": "A React hooks library for ink! contracts", diff --git a/packages/useink/src/core/substrate/timestamp/getTimestamp.ts b/packages/useink/src/core/substrate/timestamp/getTimestamp.ts deleted file mode 100644 index 1dcae77..0000000 --- a/packages/useink/src/core/substrate/timestamp/getTimestamp.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ApiPromise, QueryableModuleCalls } from '../../types/index'; - -export const getTimestamp = ( - api: ApiPromise | undefined, -): QueryableModuleCalls<'promise'> | undefined => api?.query?.timestamp; diff --git a/packages/useink/src/core/substrate/timestamp/getTimestampDate.ts b/packages/useink/src/core/substrate/timestamp/getTimestampDate.ts new file mode 100644 index 0000000..970d5d6 --- /dev/null +++ b/packages/useink/src/core/substrate/timestamp/getTimestampDate.ts @@ -0,0 +1,12 @@ +import { unixMilliToDate } from '../../../utils'; +import { ApiBase } from '../../types/index'; +import { getTimestampUnix } from './getTimestampNow.ts'; + +export const getTimestampDate = async ( + api: ApiBase<'promise'> | undefined, +): Promise => { + const now = await getTimestampUnix(api); + if (!now) return; + + return unixMilliToDate(now); +}; diff --git a/packages/useink/src/core/substrate/timestamp/getTimestampNow.ts b/packages/useink/src/core/substrate/timestamp/getTimestampNow.ts index 22e38ec..9137863 100644 --- a/packages/useink/src/core/substrate/timestamp/getTimestampNow.ts +++ b/packages/useink/src/core/substrate/timestamp/getTimestampNow.ts @@ -1,11 +1,14 @@ -import { ApiPromise, Codec } from '../../types/index'; -import { getTimestamp } from './getTimestamp.ts'; +import { ApiBase } from '../../types/index'; +import { getTimestampQuery } from './getTimestampQuery.ts'; -export const getTimestampNow = async ( - api: ApiPromise | undefined, -): Promise => { - const timestamp = getTimestamp(api); - if (!timestamp?.now) return; +export const getTimestampUnix = async ( + api: ApiBase<'promise'> | undefined, +): Promise => { + const query = getTimestampQuery(api); + if (!query?.now) return; - return await timestamp.now(); + const t = await query.now(); + const stringWithoutCommas = t.toHuman()?.toString().split(',').join(''); + + return stringWithoutCommas ? parseInt(stringWithoutCommas) : undefined; }; diff --git a/packages/useink/src/core/substrate/timestamp/getTimestampQuery.ts b/packages/useink/src/core/substrate/timestamp/getTimestampQuery.ts new file mode 100644 index 0000000..d2bf9f9 --- /dev/null +++ b/packages/useink/src/core/substrate/timestamp/getTimestampQuery.ts @@ -0,0 +1,5 @@ +import { ApiBase, QueryableModuleCalls } from '../../types/index'; + +export const getTimestampQuery = ( + api: ApiBase<'promise'> | undefined, +): QueryableModuleCalls<'promise'> | undefined => api?.query?.timestamp; diff --git a/packages/useink/src/core/substrate/timestamp/index.ts b/packages/useink/src/core/substrate/timestamp/index.ts index f7afd06..15d4388 100644 --- a/packages/useink/src/core/substrate/timestamp/index.ts +++ b/packages/useink/src/core/substrate/timestamp/index.ts @@ -1,2 +1,3 @@ -export * from './getTimestamp.ts'; +export * from './getTimestampDate.ts'; export * from './getTimestampNow.ts'; +export * from './getTimestampQuery.ts'; diff --git a/packages/useink/src/react/hooks/helpers/index.ts b/packages/useink/src/react/hooks/helpers/index.ts new file mode 100644 index 0000000..f619c36 --- /dev/null +++ b/packages/useink/src/react/hooks/helpers/index.ts @@ -0,0 +1 @@ +export * from './useUnixMilliToDate'; diff --git a/packages/useink/src/react/hooks/helpers/useUnixMilliToDate.ts b/packages/useink/src/react/hooks/helpers/useUnixMilliToDate.ts new file mode 100644 index 0000000..f78fec7 --- /dev/null +++ b/packages/useink/src/react/hooks/helpers/useUnixMilliToDate.ts @@ -0,0 +1,7 @@ +import { unixMilliToDate } from '../../../utils/helpers/unixMilliToDate'; +import { useMemo } from 'react'; + +export const useUnixMilliToDate = ( + unixInMilliSeconds: number | undefined, +): Date | undefined => + useMemo(() => unixMilliToDate(unixInMilliSeconds), [unixInMilliSeconds]); diff --git a/packages/useink/src/react/hooks/index.ts b/packages/useink/src/react/hooks/index.ts index ac7648d..7938a12 100644 --- a/packages/useink/src/react/hooks/index.ts +++ b/packages/useink/src/react/hooks/index.ts @@ -1,4 +1,5 @@ export * from './config/index'; export * from './contracts/index'; +export * from './helpers/index'; export * from './substrate/index'; export * from './wallets/index'; diff --git a/packages/useink/src/react/hooks/substrate/balance/index.ts b/packages/useink/src/react/hooks/substrate/balance/index.ts new file mode 100644 index 0000000..32eefbe --- /dev/null +++ b/packages/useink/src/react/hooks/substrate/balance/index.ts @@ -0,0 +1 @@ +export * from './useBalance'; diff --git a/packages/useink/src/react/hooks/substrate/useBalance.ts b/packages/useink/src/react/hooks/substrate/balance/useBalance.ts similarity index 65% rename from packages/useink/src/react/hooks/substrate/useBalance.ts rename to packages/useink/src/react/hooks/substrate/balance/useBalance.ts index 50656ca..c1c3427 100644 --- a/packages/useink/src/react/hooks/substrate/useBalance.ts +++ b/packages/useink/src/react/hooks/substrate/balance/useBalance.ts @@ -1,9 +1,9 @@ -import { ChainId } from '../../../chains/index'; -import { DeriveBalancesAccount, WithAddress } from '../../../core/index'; -import { getBalance } from '../../../core/index'; -import { useChain } from '../index'; -import { useApi } from '../substrate/useApi.ts'; -import { useBlockHeader } from './useBlockHeader.ts'; +import { ChainId } from '../../../../chains/index'; +import { DeriveBalancesAccount, WithAddress } from '../../../../core/index'; +import { getBalance } from '../../../../core/index'; +import { useChain } from '../../index'; +import { useApi } from '../useApi.ts'; +import { useBlockHeader } from '../useBlockHeader.ts'; import { useEffect, useState } from 'react'; export const useBalance = ( diff --git a/packages/useink/src/react/hooks/substrate/index.ts b/packages/useink/src/react/hooks/substrate/index.ts index c121fdf..37415b0 100644 --- a/packages/useink/src/react/hooks/substrate/index.ts +++ b/packages/useink/src/react/hooks/substrate/index.ts @@ -1,5 +1,6 @@ +export * from './balance'; +export * from './timestamp'; export * from './useApi.ts'; -export * from './useBalance.ts'; export * from './useBlockHeader.ts'; export * from './useChainDecimals.ts'; export * from './useTokenSymbol.ts'; diff --git a/packages/useink/src/react/hooks/substrate/timestamp/index.ts b/packages/useink/src/react/hooks/substrate/timestamp/index.ts new file mode 100644 index 0000000..a3a9888 --- /dev/null +++ b/packages/useink/src/react/hooks/substrate/timestamp/index.ts @@ -0,0 +1,3 @@ +export * from './useTimestampDate'; +export * from './useTimestampNow'; +export * from './useTimestampQuery'; diff --git a/packages/useink/src/react/hooks/substrate/timestamp/useTimestampDate.ts b/packages/useink/src/react/hooks/substrate/timestamp/useTimestampDate.ts new file mode 100644 index 0000000..40b6dab --- /dev/null +++ b/packages/useink/src/react/hooks/substrate/timestamp/useTimestampDate.ts @@ -0,0 +1,9 @@ +import { ChainId } from '../../../../chains'; +import { useUnixMilliToDate } from '../../helpers'; +import { useTimestampNow } from './useTimestampNow'; + +export const useTimestampDate = (chainId?: ChainId): Date | undefined => { + const unix = useTimestampNow(chainId); + + return useUnixMilliToDate(unix); +}; diff --git a/packages/useink/src/react/hooks/substrate/timestamp/useTimestampNow.ts b/packages/useink/src/react/hooks/substrate/timestamp/useTimestampNow.ts new file mode 100644 index 0000000..9b8a9f7 --- /dev/null +++ b/packages/useink/src/react/hooks/substrate/timestamp/useTimestampNow.ts @@ -0,0 +1,18 @@ +import { ChainId } from '../../../../chains'; +import { getTimestampUnix } from '../../../../core'; +import { useApi } from '../useApi'; +import { useBlockHeader } from '../useBlockHeader'; +import { useEffect, useState } from 'react'; + +// Get the current timestamp in milliseconds +export const useTimestampNow = (chainId?: ChainId): number | undefined => { + const [now, setNow] = useState(); + const b = useBlockHeader(chainId); + const chainApi = useApi(chainId); + + useEffect(() => { + getTimestampUnix(chainApi?.api).then(setNow).catch(); + }, [b?.blockNumber]); + + return now; +}; diff --git a/packages/useink/src/react/hooks/substrate/timestamp/useTimestampQuery.ts b/packages/useink/src/react/hooks/substrate/timestamp/useTimestampQuery.ts new file mode 100644 index 0000000..d0121ea --- /dev/null +++ b/packages/useink/src/react/hooks/substrate/timestamp/useTimestampQuery.ts @@ -0,0 +1,19 @@ +import { ChainId } from '../../../../chains'; +import { QueryableModuleCalls, getTimestampQuery } from '../../../../core'; +import { useApi } from '../useApi'; +import { useEffect, useState } from 'react'; + +// Get a queryable function that can then be used to call a chain: `await timestampQuery.now()` +export const useTimestampQuery = ( + chainId?: ChainId, +): QueryableModuleCalls<'promise'> | undefined => { + const chainApi = useApi(chainId); + const [timestamp, setTimestamp] = useState>(); + + useEffect(() => { + const t = getTimestampQuery(chainApi?.api); + setTimestamp(t); + }, [chainApi?.api]); + + return timestamp; +}; diff --git a/packages/useink/src/utils/helpers/index.ts b/packages/useink/src/utils/helpers/index.ts index 0cfa358..54e61a0 100644 --- a/packages/useink/src/utils/helpers/index.ts +++ b/packages/useink/src/utils/helpers/index.ts @@ -1,3 +1,4 @@ export * from './getExpiredItem.ts'; export * from './parseUnits'; export * from './pseudoRandomId.ts'; +export * from './unixMilliToDate.ts'; diff --git a/packages/useink/src/utils/helpers/unixMilliToDate.ts b/packages/useink/src/utils/helpers/unixMilliToDate.ts new file mode 100644 index 0000000..d548cc0 --- /dev/null +++ b/packages/useink/src/utils/helpers/unixMilliToDate.ts @@ -0,0 +1,4 @@ +export const unixMilliToDate = ( + unixInMilliSeconds: number | undefined, +): Date | undefined => + unixInMilliSeconds ? new Date(unixInMilliSeconds) : undefined; diff --git a/playground/src/components/pg-home/HomePage.tsx b/playground/src/components/pg-home/HomePage.tsx index e09403e..491db4c 100644 --- a/playground/src/components/pg-home/HomePage.tsx +++ b/playground/src/components/pg-home/HomePage.tsx @@ -15,6 +15,8 @@ import { useEventSubscription, useEvents, useInstalledWallets, + useTimestampDate, + useTimestampNow, useTokenSymbol, useTx, useTxPaymentInfo, @@ -77,6 +79,8 @@ export const HomePage: React.FC = () => { const panic = useCall(cRococoContract, 'panic'); const assertBoom = useCall(cRococoContract, 'assertBoom'); const mood = useCall(cRococoContract, 'mood'); + const phalaTimestamp = useTimestampNow('phala'); + const phalaDate = useTimestampDate('phala'); const shibuyaContract = useContract( SHIBUYA_CONTRACT_ADDRESS, metadata, @@ -271,6 +275,7 @@ export const HomePage: React.FC = () => { {planckToDecimalFormatted( balance?.freeBalance, cRococoContract.contract.api, + { decimals: 4 }, )} @@ -336,6 +341,19 @@ export const HomePage: React.FC = () => { +
  • + + Phala's current timestamp:{' '} + + {phalaTimestamp} + + + +

    + Phala's last block time: {phalaDate?.toLocaleTimeString()} +

    +
  • +