remove singleton, revert back to using single const

This commit is contained in:
Einhornimmond 2023-07-06 16:04:22 +02:00
parent 89ceb1d27b
commit 6ee8dda4ce
4 changed files with 54 additions and 117 deletions

View File

@ -1,35 +1,11 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { IotaClientSingleton } from '@/client/IotaClientSingleton'
import { sendDataMessage, getMessage } from '@/client/IotaClient'
import CONFIG from '@/config'
import { logger } from '@/server/logger'
import { MessageWrapper } from '@iota/client/lib/types'
describe('apis/IotaClientSingleton/disabled', () => {
beforeEach(() => {
CONFIG.IOTA = false
})
it('getInstance return undefined if iota is disabled', () => {
const spyLog = jest.spyOn(logger, 'info')
expect(IotaClientSingleton.getInstance()).toBeUndefined()
expect(spyLog).toHaveBeenCalledWith('Iota are disabled via config...')
})
})
describe('apis/IotaClientSingleton/invalidIotaUrl', () => {
beforeEach(() => {
CONFIG.IOTA = true
CONFIG.IOTA_API_URL = 'invalidUrl'
})
it('throw exception on invalid iota url', () => {
// eslint-disable-next-line jest/unbound-method
expect(IotaClientSingleton.getInstance).toThrow()
})
})
describe('apis/IotaClientSingleton/enabled', () => {
describe('Hello World', () => {
beforeEach(() => {
CONFIG.IOTA = true
CONFIG.IOTA_COMMUNITY_ALIAS = 'GRADIDO: TestHelloWelt2'
CONFIG.IOTA_API_URL = 'https://chrysalis-nodes.iota.org'
})
@ -41,7 +17,7 @@ describe('apis/IotaClientSingleton/enabled', () => {
const indexHexString = Buffer.from(CONFIG.IOTA_COMMUNITY_ALIAS, 'utf8').toString('hex')
let iotaMessage: MessageWrapper | undefined
it('sends hello world message to iota tangle', async () => {
iotaMessage = await IotaClientSingleton.getInstance()?.sendDataMessage(messageString)
iotaMessage = await sendDataMessage(messageString)
expect(iotaMessage).toMatchObject({
message: {
payload: {
@ -57,7 +33,7 @@ describe('apis/IotaClientSingleton/enabled', () => {
// to able to test it even when send failed
messageId =
iotaMessage?.messageId ?? '5498130bc3918e1a7143969ce05805502417e3e1bd596d3c44d6a0adeea22710'
iotaMessage = await IotaClientSingleton.getInstance()?.getMessage(messageId)
iotaMessage = await getMessage(messageId)
expect(iotaMessage).toMatchObject({
message: {
payload: {

View File

@ -0,0 +1,51 @@
import { ClientBuilder } from '@iota/client'
import { MessageWrapper } from '@iota/client/lib/types'
import CONFIG from '@/config'
const client = new ClientBuilder().node(CONFIG.IOTA_API_URL).build()
/**
* send data message onto iota tangle
* use CONFIG.IOTA_COMMUNITY_ALIAS for index
* @param {string} message - the message as utf based string, will be converted to hex automatically from @iota/client
* @return {Promise<MessageWrapper>} the iota message typed
*/
function sendDataMessage(message: string): Promise<MessageWrapper> {
return client.message().index(CONFIG.IOTA_COMMUNITY_ALIAS).data(message).submit()
}
/**
* receive message for known message id from iota tangle
* @param {string} messageId - as hex string
* @return {Promise<MessageWrapper>} the iota message typed
*/
function getMessage(messageId: string): Promise<MessageWrapper> {
return client.getMessage().data(messageId)
}
export { sendDataMessage, getMessage }
/**
* example for message:
```json
{
message: {
networkId: '1454675179895816119',
parentMessageIds: [
'5f30efecca59fdfef7c103e85ef691b2b1dc474e9eae9056888a6d58605083e7',
'77cef2fb405daedcd7469e009bb87a6d9a4840e618cdb599cd21a30a9fec88dc',
'7d2cfb39f40585ba568a29ad7e85c1478b2584496eb736d4001ac344f6a6cacf',
'c66da602874220dfa26925f6be540d37c0084d37cd04726fcc5be9d80b36f850'
],
payload: {
type: 2,
index: '4752414449444f3a205465737448656c6c6f57656c7431',
data: '48656c6c6f20576f726c64202d20546875204a756e20303820323032332031343a35393a343520474d542b3030303020284b6f6f7264696e69657274652057656c747a65697429'
},
nonce: '13835058055282465157'
},
messageId: '5498130bc3918e1a7143969ce05805502417e3e1bd596d3c44d6a0adeea22710'
}
```
*/

View File

@ -1,89 +0,0 @@
import { Client, ClientBuilder } from '@iota/client'
import { MessageWrapper } from '@iota/client/lib/types'
import CONFIG from '@/config'
import { logger } from '@/server/logger'
// Source: https://refactoring.guru/design-patterns/singleton/typescript/example
// and ../federation/client/FederationClientFactory.ts
/**
* A Singleton class defines the `getInstance` method that lets clients access
* the unique singleton instance.
*/
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
class IotaClientSingleton {
// eslint-disable-next-line no-use-before-define
private static instance: IotaClientSingleton
private client: Client
/**
* The Singleton's constructor should always be private to prevent direct
* construction calls with the `new` operator.
*/
// eslint-disable-next-line no-useless-constructor, @typescript-eslint/no-empty-function
private constructor() {}
/**
* The static method that controls the access to the singleton instance.
*
* This implementation let you subclass the Singleton class while keeping
* just one instance of each subclass around.
*/
public static getInstance(): IotaClientSingleton | undefined {
if (!CONFIG.IOTA || !CONFIG.IOTA_API_URL) {
logger.info(`Iota are disabled via config...`)
return
}
if (!IotaClientSingleton.instance) {
const client = new ClientBuilder().node(CONFIG.IOTA_API_URL).build()
IotaClientSingleton.instance = new IotaClientSingleton()
IotaClientSingleton.instance.client = client
}
return IotaClientSingleton.instance
}
/**
* send data message onto iota tangle
* use CONFIG.IOTA_COMMUNITY_ALIAS for index
* @param {string} message - the message as utf based string, will be converted to hex automatically from @iota/client
* @return {Promise<MessageWrapper>} the iota message typed
*/
public sendDataMessage(message: string): Promise<MessageWrapper> {
return this.client.message().index(CONFIG.IOTA_COMMUNITY_ALIAS).data(message).submit()
}
/**
* receive message for known message id from iota tangle
* @param {string} messageId - as hex string
* @return {Promise<MessageWrapper>} the iota message typed
*/
public getMessage(messageId: string): Promise<MessageWrapper> {
return this.client.getMessage().data(messageId)
}
}
export { IotaClientSingleton }
/**
* example for message:
```json
{
message: {
networkId: '1454675179895816119',
parentMessageIds: [
'5f30efecca59fdfef7c103e85ef691b2b1dc474e9eae9056888a6d58605083e7',
'77cef2fb405daedcd7469e009bb87a6d9a4840e618cdb599cd21a30a9fec88dc',
'7d2cfb39f40585ba568a29ad7e85c1478b2584496eb736d4001ac344f6a6cacf',
'c66da602874220dfa26925f6be540d37c0084d37cd04726fcc5be9d80b36f850'
],
payload: {
type: 2,
index: '4752414449444f3a205465737448656c6c6f57656c7431',
data: '48656c6c6f20576f726c64202d20546875204a756e20303820323032332031343a35393a343520474d542b3030303020284b6f6f7264696e69657274652057656c747a65697429'
},
nonce: '13835058055282465157'
},
messageId: '5498130bc3918e1a7143969ce05805502417e3e1bd596d3c44d6a0adeea22710'
}
```
*/

View File

@ -18,7 +18,6 @@ const server = {
}
const iota = {
IOTA: process.env.IOTA === 'true' || false,
IOTA_API_URL: process.env.IOTA_API_URL ?? 'https://chrysalis-nodes.iota.org',
IOTA_COMMUNITY_ALIAS: process.env.IOTA_COMMUNITY_ALIAS ?? 'GRADIDO: TestHelloWelt2',
}