Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/tatum logs #1036

Closed
wants to merge 11 commits into from
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
},
"dependencies": {
"bignumber.js": "^9.1.1",
"chalk": "4.1.2",
"reflect-metadata": "^0.1.13",
"typedi": "^0.10.0"
},
Expand Down
9 changes: 8 additions & 1 deletion src/service/faucet/faucet.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Container, Service } from 'typedi'

Check warning on line 1 in src/service/faucet/faucet.ts

View workflow job for this annotation

GitHub Actions / test

'Service' is defined but never used

import { TatumConnector } from '../../connector/tatum.connector'
import { CONFIG, ErrorUtils, ResponseDto } from '../../util'
import { CONFIG, ErrorUtils, ResponseDto, TatumLogger } from '../../util'
import { Network, TatumConfig } from '../tatum'

import { TxIdResponse } from './faucet.dto'
Expand All @@ -12,7 +12,7 @@
},
transient: true,
})
export class Faucet {

Check warning on line 15 in src/service/faucet/faucet.ts

View workflow job for this annotation

GitHub Actions / test

'Faucet' is defined but never used
private readonly connector: TatumConnector
private readonly config: TatumConfig

Expand All @@ -22,6 +22,13 @@
}

async fund(address: string): Promise<ResponseDto<TxIdResponse>> {
if (!this.config.quiet && !this.config.apiKey?.v4) {
TatumLogger.error(
'Unable to make Faucet Calls, get an api key to successfully use this feature - ',
'https://co.tatum.io/signup',
)
}

const chain = this.convertToFaucetChain(this.config.network)

return ErrorUtils.tryFail(async () => {
Expand Down
5 changes: 5 additions & 0 deletions src/service/tatum/tatum.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ export interface TatumConfig {
* Optional list of TatumSdkWalletExtensions.
*/
configureWalletProviders?: WalletProviderConstructorOrConfig[]

/**
* If this is set to `true`, you will not be receiving verbose logs such as welcome message or additional information about errors.
*/
quiet?: boolean
}

export enum ApiVersion {
Expand Down
34 changes: 21 additions & 13 deletions src/service/tatum/tatum.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Container, Service } from 'typedi'
import { isLoadBalancerNetwork } from '../../dto'
import { CONFIG, Constant, Utils } from '../../util'
import { CONFIG, Constant, TatumLogger, Utils } from '../../util'
import {
ExtensionConstructor,
ExtensionConstructorOrConfig,
Expand Down Expand Up @@ -83,23 +83,31 @@ export class TatumSDK {
}

const mergedConfig = Utils.deepMerge(defaultConfig, config) as TatumConfig
const keyProvided = !!mergedConfig.apiKey

// TODO: check when rpc is customized if there is allowedBlocksBehind if not throw error or set default
// TODO: Check if rpc works for other chains and all configurations are set correctly
try {
if (!mergedConfig.quiet) TatumLogger.welcome(keyProvided)

const id = TatumSDK.generateRandomString()
Container.of(id).set(CONFIG, mergedConfig)
if (isLoadBalancerNetwork(mergedConfig.network)) {
const loadBalancer = Container.of(id).get(LoadBalancer)
await loadBalancer.init()
}
// TODO: check when rpc is customized if there is allowedBlocksBehind if not throw error or set default
// TODO: Check if rpc works for other chains and all configurations are set correctly

const id = TatumSDK.generateRandomString()
Container.of(id).set(CONFIG, mergedConfig)
if (isLoadBalancerNetwork(mergedConfig.network)) {
const loadBalancer = Container.of(id).get(LoadBalancer)
await loadBalancer.init()
}

const containerInstance = new TatumSdkContainer(Container.of(id))
const containerInstance = new TatumSdkContainer(Container.of(id))

await this.configureExtensions(config, id, containerInstance)
await this.addBuiltInExtensions(id, containerInstance)
await this.configureExtensions(config, id, containerInstance)
await this.addBuiltInExtensions(id, containerInstance)

return Utils.getClient<T>(id, mergedConfig.network)
return Utils.getClient<T>(id, mergedConfig.network)
} catch (e) {
if (!mergedConfig.quiet) TatumLogger.welcome(keyProvided, true)
throw e
}
}

private static builtInExtensions: ExtensionConstructor[] = [MetaMask]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
CreateFungibleToken,
CreateNftCollection,
} from '../../../dto/walletProvider'
import { Constant, Utils } from '../../../util'
import { Constant, TatumLogger, Utils } from '../../../util'
import { ITatumSdkContainer, TatumSdkWalletProvider } from '../../extensions'
import { EvmRpc } from '../../rpc'
import { TatumConfig } from '../../tatum'
Expand All @@ -30,6 +30,12 @@ export class MetaMask extends TatumSdkWalletProvider<string, TxPayload> {
* @returns address of the connected account.
*/
async getWallet(): Promise<string> {
if (!this.config.quiet) {
TatumLogger.info(
'You can get FREE testnet tokens to work with on any number of chains - ',
'https://co.tatum.io/faucets',
)
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
if (typeof window.ethereum === 'undefined') {
Expand Down
1 change: 1 addition & 0 deletions src/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './constant'
export * from './di.tokens'
export * from './error'
export * from './logger'
export * from './tatum.utils'
export * from './util.shared'
200 changes: 200 additions & 0 deletions src/util/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
import chalk from 'chalk'

type Color = 'yellow' | 'green' | 'cyan' | 'red' | 'blue'

type LogType = 'error' | 'warning' | 'info'

const log = console.log

const isBrowser = () => typeof window !== 'undefined'

// eslint-disable-next-line no-control-regex
const removeAnsi = (text: string) => text.replace(/\x1B\[\d+m|\n/g, '')

const getRandomStr = (strs: string[]) => strs[Math.floor(Math.random() * strs.length)]

const getConfigByType = (type: LogType): { color: Color; label: string } => {
switch (type) {
case 'error':
return { color: 'red', label: 'ERROR' }
case 'warning':
return { color: 'yellow', label: 'WARNING' }
case 'info':
return { color: 'cyan', label: 'INFO' }
}
}

const getStyleByType = (type?: LogType) => {
const common = 'color: white; font-weight: bold;'

switch (type) {
case 'error':
return `${common} background-color: red`
case 'warning':
return `${common} background-color: darkorange`
case 'info':
return `${common} background-color: steelblue`
default:
return `${common} background-image: linear-gradient(126deg,#513bff 9%,#89ffca 97%);`
}
}

const getStyleByColor = (color: Color) => {
switch (color) {
case 'red':
return 'color: red;'
case 'blue':
return 'color: blue;'
case 'cyan':
return 'color: cyan;'
case 'yellow':
return 'color: yellow;'
case 'green':
return 'color: green;'
}
}

const center = (message: string, pl = 0) => {
const messageWithoutAnsi = removeAnsi(message)
const align = ((process?.stdout?.columns || 0) - (messageWithoutAnsi?.length || 0)) / 2

if (!align || align <= pl) return message

try {
return ' '.repeat(align + pl) + message
} catch {
return message
}
}

const colorize = (message: string, color: Color, block?: boolean) => {
if (isBrowser()) {
return `%c${message}%c`
}
return block ? chalk.bgKeyword(color).bold.white(message) : chalk[color](message)
}

const link = (message: string) => colorize(message, 'cyan')

const highlight = (message: string) => colorize(message, 'yellow')

const getLine = (count?: number) => {
const cols = count || process?.stdout?.columns || 53
return center(chalk.blue('-'.repeat(cols)))
}

const getBorder = () => `\n${getLine()}\n`

const getLogo = () => {
if (isBrowser()) {
return '%c Tatum %c '
}

const logoExtraPadding = 5
const logoHorizontal = '#'.repeat(logoExtraPadding + 2)

const logoGreenHorizontal = chalk.green(logoHorizontal)
const logoBlueHorizontal = chalk.blue(logoHorizontal)

return (
center(logoGreenHorizontal + '\n', logoExtraPadding) +
center(`${logoBlueHorizontal} ${logoGreenHorizontal}\n`) +
center(logoBlueHorizontal + '\n\n', 0 - logoExtraPadding) +
center(chalk.blue('#'.repeat(logoExtraPadding)) + '\n').repeat(4)
)
}

const printLog = (message: string, type: LogType, url?: string) => {
const config = getConfigByType(type)

const label = colorize(` ${config.label} `, config.color, true)

if (isBrowser()) {
log(
`${getLogo()} ${label}\n\n${message}${url}`,
getStyleByType(),
undefined,
getStyleByType(type),
undefined,
)
} else {
const border = getBorder()

log(border)
log(`${label} ${message}${url ? link(url) : ''}`)
log(border)
}
}

export const TatumLogger = {
info: (message: string, url?: string) => printLog(message, 'info', url),
warning: (message: string, url?: string) => printLog(message, 'warning', url),
error: (message: string, url?: string) => printLog(message, 'error', url),
welcome: (keyProvided: boolean, err?: boolean) => {
const logo = getLogo()
const hello = ' Welcome to Tatum! 👋'

const start = err
? `Kick off your development journey by making your first call with ${highlight('Tatum')} - ${link(
'https://tatum-get-started.io',
)}`
: getRandomStr([
`Kickstart your development journey with Tatum, check out the ${highlight(
'available features',
)} - ${link('https://tatum-features.io')}`,
`The possibilities are endless, explore ${highlight(
'applications',
)} you can build with Tatum - ${link('https://tatum-applications.io')}`,
])

const dashboard = keyProvided
? `Effortlessly track your usage & insights on your ${highlight('Tatum Dashboard')} - ${link(
'https://tatum-dashboard-usage.io',
)}`
: `Unlock higher limits: Generate an API Key by accessing your ${highlight('Dashboard')} - ${link(
'https://tatum-dashboard.io',
)}`

const features = `Try our new ${highlight('Tatum Faucets')} to get ${highlight(
'Testnet Tokens',
)} for free on over 5 chains - ${link('https://tatum-faucets.io')}`

if (isBrowser()) {
log(
`${logo}${hello}\n\n${start}\n\n${dashboard}\n\n${features}`,
getStyleByType(),
'',
getStyleByColor('yellow'),
'',
'',
'',
getStyleByColor('yellow'),
'',
'',
'',
getStyleByColor('yellow'),
'',
getStyleByColor('yellow'),
'',
'',
'',
)
} else {
const titleLine = getLine(21)
const border = getBorder()

log(border)
log(logo)

log(titleLine)
log(center(chalk.green(hello)))
log(titleLine, '\n')

log(center(start), '\n')
log(center(dashboard), '\n')
log(center(features))

log(border)
}
},
}
16 changes: 8 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,14 @@ caniuse-lite@^1.0.30001541:
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz"
integrity sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==

[email protected], chalk@^4.0.0:
version "4.1.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"

chalk@^2.0.0, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
Expand All @@ -1120,14 +1128,6 @@ chalk@^2.0.0, chalk@^2.4.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"

chalk@^4.0.0:
version "4.1.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"

char-regex@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz"
Expand Down
Loading