@baking-bad/tezos-etherlink-bridge-sdk
Version:
SDK designed for building token bridge applications between Tezos (L1) and Etherlink (L2)
4 lines • 271 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../src/common/errors.ts", "../../src/utils/memoize.ts", "../../src/utils/guards.ts", "../../src/utils/textUtils.ts", "../../src/utils/tezosUtils.ts", "../../src/utils/tokenUtils.ts", "../../src/utils/etherlinkUtils.ts", "../../src/utils/bridgeUtils.ts", "../../src/bridgeCore/bridgeOperations.ts", "../../src/utils/index.ts", "../../src/common/remoteService.ts", "../../src/common/eventEmitter.ts", "../../src/common/timeoutScheduler.ts", "../../src/logging/logMessages.ts", "../../src/logging/logger.ts", "../../src/tokenBridge/errors.ts", "../../src/tokenBridge/tokenBridge.ts", "../../src/bridgeBlockchainService/taquitoTezosBridgeBlockchainService/taquitoTezosBridgeBlockchainService.ts", "../../src/bridgeBlockchainService/taquitoTezosBridgeBlockchainService/errors.ts", "../../src/bridgeBlockchainService/taquitoTezosBridgeBlockchainService/helpers/fa12helper.ts", "../../src/bridgeBlockchainService/taquitoTezosBridgeBlockchainService/helpers/fa2helper.ts", "../../src/bridgeBlockchainService/taquitoTezosBridgeBlockchainService/tezosTicketerContentMichelsonType.ts", "../../src/bridgeBlockchainService/taquitoTezosBridgeBlockchainService/taquitoContractTezosBridgeBlockchainService.ts", "../../src/bridgeBlockchainService/taquitoTezosBridgeBlockchainService/taquitoWalletTezosBridgeBlockchainService.ts", "../../src/bridgeBlockchainService/etherlinkBridgeBlockchainService/abi/nativeTokenBridgePrecompile.ts", "../../src/bridgeBlockchainService/etherlinkBridgeBlockchainService/abi/nonNativeTokenBridgePrecompile.ts", "../../src/bridgeBlockchainService/etherlinkBridgeBlockchainService/defaultAddresses.ts", "../../src/bridgeBlockchainService/web3EtherlinkBridgeBlockchainService/web3EtherlinkBridgeBlockchainService.ts", "../../src/bridgeBlockchainService/ethersEtherlinkBridgeBlockchainService/ethersV5EtherlinkBridgeBlockchainService.ts", "../../src/bridgeBlockchainService/ethersEtherlinkBridgeBlockchainService/ethersEtherlinkBridgeBlockchainService.ts", "../../src/bridgeDataProviders/tokensBridgeDataProvider/localTokensBridgeDataProvider.ts", "../../src/bridgeDataProviders/balancesBridgeDataProvider/tzKTBalancesProvider/errors.ts", "../../src/bridgeDataProviders/balancesBridgeDataProvider/tzKTBalancesProvider/mappers.ts", "../../src/bridgeDataProviders/balancesBridgeDataProvider/tzKTBalancesProvider/tzKTBalancesProvider.ts", "../../src/bridgeDataProviders/balancesBridgeDataProvider/etherlinkNodeBalancesProvider/error.ts", "../../src/bridgeDataProviders/balancesBridgeDataProvider/etherlinkNodeBalancesProvider/etherlinkNodeBalancesProvider.ts", "../../src/bridgeDataProviders/dipDupBridgeDataProvider/dipDupGraphQLQueryBuilder/queryParts/bridgeOperationsFields.ts", "../../src/bridgeDataProviders/dipDupBridgeDataProvider/dipDupGraphQLQueryBuilder/queryParts/bridgeDepositFields.ts", "../../src/bridgeDataProviders/dipDupBridgeDataProvider/dipDupGraphQLQueryBuilder/queryParts/bridgeWithdrawalFields.ts", "../../src/bridgeDataProviders/dipDupBridgeDataProvider/dipDupGraphQLQueryBuilder/queryParts/l2TokenHolderFields.ts", "../../src/bridgeDataProviders/dipDupBridgeDataProvider/dipDupGraphQLQueryBuilder/dipDupGraphQLQueryBuilder.ts", "../../src/bridgeDataProviders/dipDupBridgeDataProvider/errors.ts", "../../src/bridgeDataProviders/dipDupBridgeDataProvider/mappers.ts", "../../src/bridgeDataProviders/dipDupBridgeDataProvider/webSocket/webSocketClient/index.browser.ts", "../../src/bridgeDataProviders/dipDupBridgeDataProvider/webSocket/dipDupWebSocketClient.ts", "../../src/bridgeDataProviders/dipDupBridgeDataProvider/dipDupBridgeDataProvider.ts", "../../src/bridgeDataProviders/defaultDataProvider/defaultDataProvider.ts"],
"sourcesContent": ["export abstract class TokenBridgeError extends Error {\n readonly name: string;\n\n constructor(message?: string, options?: ErrorOptions) {\n super(message, options);\n\n this.name = this.constructor.name;\n }\n}\n\nexport class DisposedError extends TokenBridgeError {\n}\n\nexport class RemoteServiceResponseError extends TokenBridgeError {\n constructor(status: Response['status'], content: string) {\n super(RemoteServiceResponseError.getMessage(status, content));\n }\n\n protected static getMessage(status: Response['status'], content: string): string {\n return `Response Error [Code: ${status}]. Content = ${content}`;\n }\n}\n", "const defaultEqualityCheck = <T>(a: T, b: T) => a === b;\n\nconst areArgumentsShallowlyEqual = <T extends IArguments | null>(equalityCheck: (a: T, b: T) => boolean, prev: T, next: T) => {\n if (prev === null || next === null || prev.length !== next.length) {\n return false;\n }\n\n // Do this in a for loop (and not a `forEach` or an `every`) so we can determine equality as fast as possible.\n const length = prev.length;\n for (let i = 0; i < length; i++) {\n if (!equalityCheck(prev[i], next[i])) {\n return false;\n }\n }\n\n return true;\n};\n\n/* eslint-disable prefer-rest-params */\n/* eslint-disable prefer-spread */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport const memoize = <TF extends (...args: any) => any>(func: TF, equalityCheck = defaultEqualityCheck): TF => {\n let lastArgs: IArguments | null = null;\n let lastResult: unknown = null;\n\n return (function () {\n if (!areArgumentsShallowlyEqual(equalityCheck, lastArgs, arguments)) {\n // apply arguments instead of spreading for performance.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n lastResult = func.apply(null, arguments as any);\n }\n\n lastArgs = arguments;\n return lastResult;\n } as TF);\n};\n/* eslint-enable prefer-spread */\n/* eslint-enable prefer-rest-params */\n/* eslint-enable @typescript-eslint/no-explicit-any */\n", "// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isArray = (arg: any): arg is any[] => {\n return Array.isArray(arg);\n};\n\nexport const isReadonlyArray = (arg: unknown): arg is readonly unknown[] => {\n return Array.isArray(arg);\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isDisposable = (arg: any): arg is Disposable => {\n return typeof arg?.[Symbol.dispose] === 'function';\n};\n", "export const trimSlashes = (value: string): string => {\n const hasFirst = value.startsWith('/');\n const hasLast = value.endsWith('/');\n\n return hasFirst && hasLast\n ? value.slice(1, -1)\n : hasFirst\n ? value.slice(1)\n : hasLast\n ? value.slice(0, -1)\n : value;\n};\n", "import { b58decode, encodeAddress } from '@taquito/utils';\n\nexport const convertAddressToBytes = (address: string, addPrefix = false): string => {\n const bytes = b58decode(address);\n\n return addPrefix ? '0x' + bytes : bytes;\n};\n\nexport const convertBytesToAddress = (bytes: string): string => {\n if (bytes.startsWith('0x'))\n bytes = bytes.substring(2);\n\n return encodeAddress(bytes);\n};\n", "import { isReadonlyArray } from './guards';\nimport type { Token, TezosToken, EtherlinkToken } from '../tokens';\n\nexport const isTezosToken = (token: Token): token is TezosToken => {\n return token.type === 'native' || token.type === 'fa1.2' || token.type === 'fa2';\n};\n\nconst convertTokenToDisplayString = (token: TezosToken | EtherlinkToken): string => {\n if (!token)\n return `[token is ${token === null ? 'null' : 'undefined'}]`;\n\n switch (token.type) {\n case 'native':\n return '[native token]';\n case 'erc20':\n return `[${token.address} | ERC-20]`;\n case 'fa1.2':\n return `[${token.address} | FA1.2]`;\n case 'fa2':\n return `[${token.address} | FA2 | Id: ${token.tokenId}]`;\n default:\n return '[unknown token type]';\n }\n};\n\nconst convertTokensToDisplayString = (tokens: ReadonlyArray<TezosToken | EtherlinkToken>): string => {\n return tokens.reduce(\n (result, token, index, tokens) => result + convertTokenToDisplayString(token) + (index < tokens.length - 1 ? ', ' : ']'),\n '['\n );\n};\n\nexport const toDisplayString = (tokenOrTokens: TezosToken | EtherlinkToken | ReadonlyArray<TezosToken | EtherlinkToken>): string => {\n return isReadonlyArray(tokenOrTokens)\n ? convertTokensToDisplayString(tokenOrTokens)\n : convertTokenToDisplayString(tokenOrTokens);\n};\n", "import * as web3Utils from 'web3-utils';\nimport * as web3Validator from 'web3-validator';\n\nexport const isAddress = (address: string): boolean => web3Validator.isAddress(address, true);\n\nconst isTransactionRegex = /^0x[0-9a-f]{64}$/;\nexport const isTransaction = (transactionHash: string) => isTransactionRegex.test(transactionHash);\n\nexport const toChecksumAddress = (address: string): string => web3Utils.toChecksumAddress(address);\n\nexport const prepareHexPrefix = (value: string, addOrRemove: boolean): string => {\n return value.startsWith('0x')\n ? addOrRemove\n ? value\n : value.substring(2)\n : addOrRemove\n ? '0x' + value\n : value;\n};\n", "import { BridgeTokenTransferKind, type BridgeTokenTransfer, type FinishedBridgeTokenDeposit, BridgeTokenTransferStatus } from '../bridgeCore';\n\nconst tokenTransferIdSeparator = '_';\nconst isEtherlinkTransaction = (operationHash: string) => operationHash.startsWith('0x');\n\nexport const getInitialOperation = (tokenTransfer: BridgeTokenTransfer) => tokenTransfer.kind === BridgeTokenTransferKind.Deposit\n ? tokenTransfer.tezosOperation\n : tokenTransfer.etherlinkOperation;\n\nexport const getTokenTransferIdOrInitialOperationHash = (tokenTransfer: BridgeTokenTransfer) => tokenTransfer.status === BridgeTokenTransferStatus.Pending\n ? getInitialOperation(tokenTransfer).hash\n : tokenTransfer.id;\n\nexport function convertOperationDataToTokenTransferId(etherlinkOperationHash: string, logIndex: number): string;\nexport function convertOperationDataToTokenTransferId(tezosOperationHash: string, counter: number, nonce: number | null): string;\nexport function convertOperationDataToTokenTransferId(operationHash: string, logIndexOrCounter: number, nonce?: number | null): string;\nexport function convertOperationDataToTokenTransferId(operationHash: string, logIndexOrCounter: number, nonce?: number | null): string {\n return !isEtherlinkTransaction(operationHash) && typeof nonce === 'number'\n ? `${operationHash}${tokenTransferIdSeparator}${logIndexOrCounter.toString(10)}${tokenTransferIdSeparator}${nonce.toString(10)}`\n : `${operationHash}${tokenTransferIdSeparator}${logIndexOrCounter.toString(10)}`;\n}\n\nexport const convertTokenTransferIdToOperationData = (\n tokenTransferId: string\n): null\n | readonly [tezosOperationHash: string, counter: number, nonce: number | null]\n | readonly [etherlinkOperationHash: string, logIndex: number] => {\n if (!tokenTransferId)\n return null;\n\n try {\n const operationData = tokenTransferId.split(tokenTransferIdSeparator);\n if (!operationData[0] || !operationData[1])\n return null;\n\n const counterOrLogIndex = Number.parseInt(operationData[1]);\n if (isEtherlinkTransaction(tokenTransferId))\n return [operationData[0], counterOrLogIndex];\n\n\n return operationData[2]\n ? [operationData[0], counterOrLogIndex, Number.parseInt(operationData[2])]\n : [operationData[0], counterOrLogIndex, null];\n }\n catch {\n //\n }\n\n return null;\n};\n\nexport const isBridgeTokenTransferOwner = (tokenTransfer: BridgeTokenTransfer, address: string): boolean => {\n return tokenTransfer.source === address || tokenTransfer.receiver === address;\n};\n\nconst operationFieldNames: ReadonlyArray<keyof FinishedBridgeTokenDeposit> = ['tezosOperation', 'etherlinkOperation'];\nconst bigIntFieldNames: ReadonlyArray<keyof FinishedBridgeTokenDeposit['etherlinkOperation' | 'tezosOperation']> = ['amount'];\nconst jsonStringifyReplacer = (_key: string, value: unknown) => typeof value === 'bigint'\n ? value.toString(10)\n : value;\n\nexport const stringifyBridgeTokenTransfer = (tokenTransfer: BridgeTokenTransfer, space?: string | number | undefined): string => {\n try {\n return JSON.stringify(tokenTransfer, jsonStringifyReplacer, space);\n }\n catch (error) {\n return '';\n }\n};\n\nexport const parseBridgeTokenTransfer = (tokenTransfer: string): BridgeTokenTransfer | null => {\n try {\n const transfer = JSON.parse(tokenTransfer);\n\n for (const operationName of operationFieldNames) {\n if (transfer[operationName]) {\n for (const bigIntFieldName of bigIntFieldNames) {\n if (transfer[operationName][bigIntFieldName]) {\n transfer[operationName][bigIntFieldName] = BigInt(transfer[operationName][bigIntFieldName]);\n }\n }\n }\n }\n\n return transfer;\n }\n catch (error) {\n return null;\n }\n};\n", "import type { TezosToken, EtherlinkToken } from '../tokens';\n\nexport interface TezosTransferTokensOperation {\n readonly blockId: number;\n readonly hash: string;\n readonly counter: number;\n readonly nonce: number | null;\n readonly amount: bigint;\n readonly token: TezosToken;\n readonly timestamp: string;\n}\n\nexport interface EtherlinkTransferTokensOperation {\n readonly blockId: number;\n readonly hash: string;\n readonly logIndex: number;\n readonly amount: bigint;\n readonly token: EtherlinkToken;\n readonly timestamp: string;\n}\n\nexport interface InitialRollupData {\n readonly outboxMessageLevel: number;\n readonly outboxMessageIndex: number;\n readonly estimatedOutboxMessageExecutionTimestamp?: string;\n readonly estimatedOutboxMessageExecutionLevel?: number;\n}\n\nexport interface CementedRollupData {\n readonly outboxMessageLevel: number;\n readonly outboxMessageIndex: number;\n readonly commitment: string;\n readonly proof: string;\n}\n\nexport type RollupData =\n | InitialRollupData\n | CementedRollupData;\n\nexport enum BridgeTokenTransferKind {\n Deposit = 0,\n Withdrawal = 1,\n DepositRevert = 2,\n WithdrawalRevert = 3\n}\n\nexport enum BridgeTokenTransferStatus {\n Pending = 0,\n Created = 100,\n Sealed = 200,\n Finished = 300,\n Failed = 400\n}\n\ninterface BridgeTokenTransferBase {\n readonly kind: BridgeTokenTransferKind;\n readonly status: BridgeTokenTransferStatus;\n readonly source: string;\n readonly receiver: string;\n}\n\nexport interface PendingBridgeTokenDeposit extends BridgeTokenTransferBase {\n readonly kind: BridgeTokenTransferKind.Deposit;\n readonly status: BridgeTokenTransferStatus.Pending;\n readonly tezosOperation: {\n readonly hash: string;\n readonly amount: bigint;\n readonly token: TezosToken;\n readonly timestamp: string;\n }\n}\n\nexport interface CreatedBridgeTokenDeposit extends BridgeTokenTransferBase {\n readonly id: string;\n readonly kind: BridgeTokenTransferKind.Deposit;\n readonly status: BridgeTokenTransferStatus.Created;\n readonly tezosOperation: TezosTransferTokensOperation;\n}\n\nexport interface FinishedBridgeTokenDeposit extends BridgeTokenTransferBase {\n readonly id: string;\n readonly kind: BridgeTokenTransferKind.Deposit;\n readonly status: BridgeTokenTransferStatus.Finished;\n readonly tezosOperation: TezosTransferTokensOperation;\n readonly etherlinkOperation: EtherlinkTransferTokensOperation;\n}\n\nexport interface FailedBridgeTokenDeposit extends BridgeTokenTransferBase {\n readonly id: string;\n readonly kind: BridgeTokenTransferKind.Deposit;\n readonly status: BridgeTokenTransferStatus.Failed;\n readonly error?: string;\n readonly tezosOperation: TezosTransferTokensOperation;\n readonly etherlinkOperation?: EtherlinkTransferTokensOperation;\n}\n\nexport type BridgeTokenDeposit =\n | PendingBridgeTokenDeposit\n | CreatedBridgeTokenDeposit\n | FinishedBridgeTokenDeposit\n | FailedBridgeTokenDeposit;\n\nexport interface PendingBridgeTokenWithdrawal extends BridgeTokenTransferBase {\n readonly kind: BridgeTokenTransferKind.Withdrawal;\n readonly status: BridgeTokenTransferStatus.Pending;\n readonly etherlinkOperation: {\n readonly hash: string;\n readonly amount: bigint;\n readonly token: EtherlinkToken;\n readonly timestamp: string;\n }\n}\n\nexport interface CreatedBridgeTokenWithdrawal extends BridgeTokenTransferBase {\n readonly id: string;\n readonly kind: BridgeTokenTransferKind.Withdrawal;\n readonly status: BridgeTokenTransferStatus.Created;\n readonly etherlinkOperation: EtherlinkTransferTokensOperation;\n readonly rollupData: InitialRollupData;\n}\n\nexport interface SealedBridgeTokenWithdrawal extends BridgeTokenTransferBase {\n readonly id: string;\n readonly kind: BridgeTokenTransferKind.Withdrawal;\n readonly status: BridgeTokenTransferStatus.Sealed;\n readonly etherlinkOperation: EtherlinkTransferTokensOperation;\n readonly rollupData: CementedRollupData;\n}\n\nexport interface FinishedBridgeTokenWithdrawal extends BridgeTokenTransferBase {\n readonly id: string;\n readonly kind: BridgeTokenTransferKind.Withdrawal;\n readonly status: BridgeTokenTransferStatus.Finished;\n readonly etherlinkOperation: EtherlinkTransferTokensOperation;\n readonly rollupData: CementedRollupData;\n readonly tezosOperation: TezosTransferTokensOperation;\n}\n\nexport interface FailedBridgeTokenWithdrawal extends BridgeTokenTransferBase {\n readonly id: string;\n readonly kind: BridgeTokenTransferKind.Withdrawal;\n readonly status: BridgeTokenTransferStatus.Failed;\n readonly error?: string;\n readonly etherlinkOperation: EtherlinkTransferTokensOperation;\n readonly rollupData?: Partial<CementedRollupData>;\n readonly tezosOperation?: TezosTransferTokensOperation;\n}\n\nexport type BridgeTokenWithdrawal =\n | PendingBridgeTokenWithdrawal\n | CreatedBridgeTokenWithdrawal\n | SealedBridgeTokenWithdrawal\n | FinishedBridgeTokenWithdrawal\n | FailedBridgeTokenWithdrawal;\n\nexport type BridgeTokenTransfer =\n | BridgeTokenDeposit\n | BridgeTokenWithdrawal;\n", "export { memoize } from './memoize';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport const emptyFunction: () => any = () => { };\nexport const emptyAsyncFunction: () => Promise<any> = async () => { };\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nexport * as guards from './guards';\nexport * as textUtils from './textUtils';\nexport * as tezosUtils from './tezosUtils';\nexport * as tokenUtils from './tokenUtils';\nexport * as etherlinkUtils from './etherlinkUtils';\nexport * as bridgeUtils from './bridgeUtils';\n", "import { RemoteServiceResponseError } from './errors';\nimport { textUtils } from '../utils';\n\nexport type RemoteServiceResponseFormat = 'none' | 'json' | 'text';\n\nexport abstract class RemoteService {\n readonly baseUrl: string;\n\n constructor(baseUrl: string) {\n this.baseUrl = textUtils.trimSlashes(baseUrl);\n }\n\n protected getUrl(uri: string) {\n return new URL(this.baseUrl + '/' + textUtils.trimSlashes(uri));\n }\n\n protected async getRequestInit(requestInit: RequestInit = {}) {\n const headers = new Headers(requestInit.headers);\n if (!headers.has('Accept'))\n headers.append('Accept', 'application/json');\n if (!headers.has('Content-Type'))\n headers.append('Content-Type', 'application/json');\n\n requestInit.headers = headers;\n return requestInit;\n }\n\n protected async fetch<T>(\n uriOrUrl: string | URL,\n responseFormat: T extends void ? 'none' : Exclude<RemoteServiceResponseFormat, 'none'>,\n requestInit?: RequestInit,\n useDefaultRequestInitFields = true\n ): Promise<T> {\n if (useDefaultRequestInitFields)\n requestInit = await this.getRequestInit(requestInit);\n\n const url = typeof uriOrUrl === 'string' ? this.getUrl(uriOrUrl) : uriOrUrl;\n const response = await fetch(url.href, requestInit);\n\n await this.ensureResponseOk(response);\n\n return responseFormat === 'none'\n ? undefined :\n (await (responseFormat === 'json' ? (response.json() as any) : response.text()));\n }\n\n protected async ensureResponseOk(response: Response) {\n if (response.ok)\n return;\n\n let content: string | undefined;\n try {\n content = await response.text();\n }\n catch {\n content = '[unavailable]';\n }\n\n throw new RemoteServiceResponseError(response.status, content);\n }\n}\n", "export interface PublicEventEmitter<T extends readonly unknown[]> {\n addListener(listener: (...args: T) => void): this;\n removeListener(listener: (...args: T) => void): this;\n removeAllListeners(): this;\n}\n\nexport class EventEmitter<T extends readonly unknown[]> implements PublicEventEmitter<T> {\n private listeners: Set<(...args: T) => void> = new Set();\n\n addListener(listener: (...args: T) => void) {\n this.listeners.add(listener);\n return this;\n }\n\n removeListener(listener: (...args: T) => void) {\n if (this.listeners.has(listener))\n this.listeners.delete(listener);\n return this;\n }\n\n removeAllListeners() {\n this.listeners = new Set();\n return this;\n }\n\n emit(...args: T) {\n if (!this.listeners.size)\n return;\n\n if (this.listeners.size === 1) {\n this.listeners.values().next().value(...args);\n } else {\n // We copy listeners to prevent an unbounded loop if there is the adding of a new event handler inside the handler; \n [...this.listeners].forEach(listener => listener(...args));\n }\n }\n}\n\nexport type ToEventEmitter<T> = T extends PublicEventEmitter<infer TArgs> ? EventEmitter<TArgs> : never;\nexport type ToEventEmitters<T> = T extends Record<infer K, PublicEventEmitter<infer TArgs>> ? Record<K, EventEmitter<TArgs>> : never;\n", "export class TimeoutScheduler implements Disposable {\n private counterExpirationWatcherId: ReturnType<typeof setTimeout> | undefined;\n private actionWatchers = new Set<ReturnType<typeof setTimeout>>();\n private _counter = 0;\n\n constructor(\n private readonly timeouts: number[],\n private readonly counterExpirationMs?: number\n ) {\n }\n\n get counter() {\n return this._counter;\n }\n\n private set counter(value: number) {\n this._counter = value;\n }\n\n [Symbol.dispose]() {\n if (this.counterExpirationWatcherId)\n clearTimeout(this.counterExpirationWatcherId);\n\n this.actionWatchers.forEach(watcher => clearTimeout(watcher));\n }\n\n setTimeout(action: () => void | Promise<void>): Promise<void> {\n return new Promise(resolve => {\n if (this.counterExpirationMs)\n this.resetCounterExpiration();\n\n const timeoutIndex = Math.min(this.counter, this.timeouts.length - 1);\n const timeout = this.timeouts[timeoutIndex];\n\n const watcherId = setTimeout(async () => {\n this.actionWatchers.delete(watcherId);\n clearTimeout(watcherId);\n await action();\n resolve();\n }, timeout);\n this.actionWatchers.add(watcherId);\n\n this.counter++;\n });\n }\n\n resetCounter() {\n this.counter = 0;\n }\n\n private resetCounterExpiration() {\n if (this.counterExpirationWatcherId)\n clearTimeout(this.counterExpirationWatcherId);\n\n this.counterExpirationWatcherId = setTimeout(() => {\n this.resetCounter();\n this.counterExpirationWatcherId = undefined;\n }, this.counterExpirationMs);\n }\n}\n", "import {\n BridgeTokenTransferKind, BridgeTokenTransferStatus,\n type BridgeTokenTransfer, type FinishedBridgeTokenDeposit\n} from '../bridgeCore';\nimport { bridgeUtils, tokenUtils } from '../utils';\n\nexport const getErrorLogMessage = (error: any): string => {\n if (!error)\n return `[error is ${error === null ? 'null' : 'undefined'}]`;\n\n if (typeof error === 'string')\n return error;\n else if (typeof error?.message === 'string')\n return error.message;\n\n return '[unknown error type]';\n};\n\nexport const getTokenLogMessage = tokenUtils.toDisplayString;\n\nexport const getBridgeTokenTransferIdLogMessage = (bridgeTokenTransfer: BridgeTokenTransfer | null | undefined): string => {\n return bridgeTokenTransfer\n ? bridgeTokenTransfer.status !== BridgeTokenTransferStatus.Pending\n ? bridgeTokenTransfer.id\n : `none (${bridgeUtils.getInitialOperation(bridgeTokenTransfer).hash})`\n : bridgeTokenTransfer === null\n ? 'null'\n : 'undefined';\n};\n\nconst getNullOrUndefinedBridgeTokenTransferLogMessage = (bridgeTokenTransfer: null | undefined): string => {\n return `Bridge Token transfer is ${bridgeTokenTransfer === null ? 'null' : 'undefined'}`;\n};\n\nexport const getBridgeTokenTransferLogMessage = (bridgeTokenTransfer: BridgeTokenTransfer | null | undefined): string => {\n return bridgeTokenTransfer\n ? `Bridge Token Transfer:\n Id: ${bridgeTokenTransfer && bridgeTokenTransfer.status !== BridgeTokenTransferStatus.Pending ? bridgeTokenTransfer.id : 'none'}\n Kind: ${BridgeTokenTransferKind[bridgeTokenTransfer.kind]}\n Status: ${BridgeTokenTransferStatus[bridgeTokenTransfer.status]}\n Source: ${bridgeTokenTransfer.source}\n Receiver: ${bridgeTokenTransfer.receiver}\n Tezos operation hash: ${(bridgeTokenTransfer as FinishedBridgeTokenDeposit)?.tezosOperation?.hash}\n Etherlink operation hash: ${(bridgeTokenTransfer as FinishedBridgeTokenDeposit)?.etherlinkOperation?.hash}\n\n`\n : getNullOrUndefinedBridgeTokenTransferLogMessage(bridgeTokenTransfer);\n};\n\nexport const getDetailedBridgeTokenTransferLogMessage = (bridgeTokenTransfer: BridgeTokenTransfer | null | undefined): string => {\n return bridgeTokenTransfer\n ? `Bridge Token Transfer [${getBridgeTokenTransferIdLogMessage(bridgeTokenTransfer)}]:\n\n${bridgeUtils.stringifyBridgeTokenTransfer(bridgeTokenTransfer, 2)}\n\n`\n : getNullOrUndefinedBridgeTokenTransferLogMessage(bridgeTokenTransfer);\n};\n\nexport const getDipDupGraphQLErrorsLogMessage = (errors: ReadonlyArray<Record<'message', string>> | undefined | null): string => {\n return errors\n ? errors.reduce((result, error, index) => `${result}\\n ${index + 1}. ${error.message};`, 'DipDup GraphQL Errors:')\n : '[no errors]';\n};\n", "import { emptyFunction, memoize } from '../utils';\n\nexport interface Logger extends Pick<typeof console, 'debug' | 'log' | 'warn' | 'error' | 'time' | 'timeEnd' | 'timeLog'> {\n}\n\nexport type LazyLogger = {\n [P in keyof Logger]: Logger[P] | null;\n};\n\nexport enum LogLevel {\n None = 0,\n\n Debug = 1,\n Information = 2,\n Warning = 3,\n Error = 4\n}\n\nconst getEmptyLoggerFactory = <TNoneFunction extends typeof emptyFunction | null>(\n noneFunction: TNoneFunction\n): TNoneFunction extends null ? LazyLogger : Logger => ({\n debug: noneFunction,\n log: noneFunction,\n warn: noneFunction,\n error: noneFunction,\n time: noneFunction,\n timeEnd: noneFunction,\n timeLog: noneFunction\n}) as TNoneFunction extends null ? LazyLogger : Logger;\nconst emptyLogger = getEmptyLoggerFactory(emptyFunction);\nconst emptyLazyLogger = getEmptyLoggerFactory(null);\n\nconst getDebugLevelLogger = memoize(\n (loggerInternal: Logger) => ({\n debug: loggerInternal.debug,\n log: loggerInternal.log,\n warn: loggerInternal.warn,\n error: loggerInternal.error,\n time: loggerInternal.time,\n timeEnd: loggerInternal.timeEnd,\n timeLog: loggerInternal.timeLog\n })\n);\nconst getDebugLevelLazyLogger = getDebugLevelLogger;\n\nconst getLogLevelLoggerFactory = <TNoneFunction extends typeof emptyFunction | null>(\n noneFunction: TNoneFunction\n): (loggerInternal: Logger) => TNoneFunction extends null ? LazyLogger : Logger => memoize(\n (loggerInternal: Logger) => ({\n debug: noneFunction,\n log: loggerInternal.log,\n warn: loggerInternal.warn,\n error: loggerInternal.error,\n time: loggerInternal.time,\n timeEnd: loggerInternal.timeEnd,\n timeLog: loggerInternal.timeLog\n }) as TNoneFunction extends null ? LazyLogger : Logger\n);\nconst getLogLevelLogger = getLogLevelLoggerFactory(emptyFunction);\nconst getLogLevelLazyLogger = getLogLevelLoggerFactory(null);\n\nconst getWarnLevelLoggerFactory = <TNoneFunction extends typeof emptyFunction | null>(\n noneFunction: TNoneFunction\n): (loggerInternal: Logger) => TNoneFunction extends null ? LazyLogger : Logger => memoize(\n (loggerInternal: Logger) => ({\n debug: noneFunction,\n log: noneFunction,\n warn: loggerInternal.warn,\n error: loggerInternal.error,\n time: noneFunction,\n timeEnd: noneFunction,\n timeLog: noneFunction\n }) as TNoneFunction extends null ? LazyLogger : Logger\n);\nconst getWarnLevelLogger = getWarnLevelLoggerFactory(emptyFunction);\nconst getWarnLevelLazyLogger = getWarnLevelLoggerFactory(null);\n\nconst getErrorLevelLoggerFactory = <TNoneFunction extends typeof emptyFunction | null>(\n noneFunction: TNoneFunction\n): (loggerInternal: Logger) => TNoneFunction extends null ? LazyLogger : Logger => memoize(\n (loggerInternal: Logger) => ({\n debug: noneFunction,\n log: noneFunction,\n warn: noneFunction,\n error: loggerInternal.error,\n time: noneFunction,\n timeEnd: noneFunction,\n timeLog: noneFunction\n }) as TNoneFunction extends null ? LazyLogger : Logger\n);\nconst getErrorLevelLogger = getErrorLevelLoggerFactory(emptyFunction);\nconst getErrorLevelLazyLogger = getErrorLevelLoggerFactory(null);\n\nclass LoggerProvider {\n private internalLogger: Logger;\n private _logLevel: LogLevel = LogLevel.Information;\n\n private _logger: Logger = emptyLogger;\n private _lazyLogger: LazyLogger = emptyLazyLogger;\n\n constructor(internalLogger: Logger, logLevel: LogLevel) {\n this.internalLogger = internalLogger;\n this._logLevel = logLevel;\n\n this.updateLogger();\n }\n\n get logger() {\n return this._logger;\n }\n\n get lazyLogger() {\n return this._lazyLogger;\n }\n\n get logLevel() {\n return this._logLevel;\n }\n\n setLogger(internalLogger: Logger) {\n this.internalLogger = internalLogger;\n this.updateLogger();\n }\n\n setLogLevel(logLevel: LogLevel) {\n this._logLevel = logLevel;\n this.updateLogger();\n }\n\n private updateLogger() {\n switch (this._logLevel) {\n case LogLevel.None:\n this._logger = emptyLogger;\n this._lazyLogger = emptyLazyLogger;\n break;\n case LogLevel.Debug:\n this._logger = getDebugLevelLogger(this.internalLogger);\n this._lazyLogger = getDebugLevelLazyLogger(this.internalLogger);\n break;\n case LogLevel.Information:\n this._logger = getLogLevelLogger(this.internalLogger);\n this._lazyLogger = getLogLevelLazyLogger(this.internalLogger);\n break;\n case LogLevel.Warning:\n this._logger = getWarnLevelLogger(this.internalLogger);\n this._lazyLogger = getWarnLevelLazyLogger(this.internalLogger);\n break;\n case LogLevel.Error:\n this._logger = getErrorLevelLogger(this.internalLogger);\n this._lazyLogger = getErrorLevelLazyLogger(this.internalLogger);\n break;\n }\n }\n}\n\nexport const loggerProvider = new LoggerProvider(console, LogLevel.None);\n", "import type { BridgeTokenTransfer } from '../bridgeCore';\nimport { DisposedError, TokenBridgeError } from '../common';\nimport { getBridgeTokenTransferIdLogMessage } from '../logging';\nimport type { TezosToken, EtherlinkToken } from '../tokens';\nimport { tokenUtils } from '../utils';\n\nexport class TokenBridgeDisposed extends DisposedError {\n constructor() {\n super('The TokenBridge is disposed.');\n }\n}\n\nexport class TokenPairNotFoundError extends TokenBridgeError {\n constructor(token: TezosToken | EtherlinkToken) {\n super(TokenPairNotFoundError.getMessage(token));\n }\n\n private static getMessage(token: TezosToken | EtherlinkToken): string {\n return `Token pair not found for the ${tokenUtils.toDisplayString(token)} token`;\n }\n}\n\nexport class InsufficientBalanceError extends TokenBridgeError {\n constructor(token: TezosToken | EtherlinkToken, address: string, balance: bigint, requested: bigint) {\n super(InsufficientBalanceError.getMessage(token, address, balance, requested));\n }\n\n private static getMessage(token: TezosToken | EtherlinkToken, address: string, balance: bigint, requested: bigint): string {\n return `${address} has an insufficient balance ${tokenUtils.toDisplayString(token)}. Balance = ${balance}. Requested = ${requested}`;\n }\n}\n\nexport class FailedTokenTransferError extends TokenBridgeError {\n constructor(tokenTransfer: BridgeTokenTransfer) {\n super(FailedTokenTransferError.getMessage(tokenTransfer));\n }\n\n private static getMessage(tokenTransfer: BridgeTokenTransfer): string {\n return `The ${getBridgeTokenTransferIdLogMessage(tokenTransfer)} token transfer is failed`;\n }\n}\n\nexport class TezosSignerAccountUnavailableError extends TokenBridgeError {\n constructor() {\n super('The Tezos signer account is unavailable');\n }\n}\n\nexport class EtherlinkSignerAccountUnavailableError extends TokenBridgeError {\n constructor() {\n super('The Etherlink signer account is unavailable');\n }\n}\n", "import { EtherlinkSignerAccountUnavailableError, FailedTokenTransferError, InsufficientBalanceError, TezosSignerAccountUnavailableError, TokenBridgeDisposed, TokenPairNotFoundError } from './errors';\nimport type { TokenBridgeComponents } from './tokenBridgeComponents';\nimport type { SignerTokenBalances, TokenBridgeDataApi } from './tokenBridgeDataApi';\nimport type { TokenBridgeOptions } from './tokenBridgeOptions';\nimport type { TokenBridgeStreamApi } from './tokenBridgeStreamApi';\nimport type { EtherlinkBridgeBlockchainService, TezosBridgeBlockchainService } from '../bridgeBlockchainService';\nimport {\n BridgeTokenTransferKind, BridgeTokenTransferStatus,\n type TokenPair,\n type DepositOptions, type DepositResult, type StartWithdrawResult, type FinishWithdrawResult,\n\n type BridgeTokenTransfer,\n type PendingBridgeTokenDeposit, type CreatedBridgeTokenDeposit, type FinishedBridgeTokenDeposit,\n type PendingBridgeTokenWithdrawal, type CreatedBridgeTokenWithdrawal, type SealedBridgeTokenWithdrawal, type FinishedBridgeTokenWithdrawal\n} from '../bridgeCore';\nimport type {\n AccountTokenBalance, AccountTokenBalances,\n BalancesFetchOptions, TokensFetchOptions, TransfersFetchOptions\n} from '../bridgeDataProviders';\nimport { EventEmitter, ToEventEmitter, type PublicEventEmitter } from '../common';\nimport {\n loggerProvider,\n getTokenLogMessage, getBridgeTokenTransferLogMessage, getDetailedBridgeTokenTransferLogMessage, getErrorLogMessage\n} from '../logging';\nimport type {\n TezosToken, NativeTezosToken, NonNativeTezosToken,\n EtherlinkToken, NativeEtherlinkToken, NonNativeEtherlinkToken\n} from '../tokens';\nimport { bridgeUtils, guards } from '../utils';\n\ninterface TokenBridgeComponentsEvents {\n readonly tokenTransferCreated: PublicEventEmitter<readonly [tokenTransfer: BridgeTokenTransfer]>;\n readonly tokenTransferUpdated: PublicEventEmitter<readonly [tokenTransfer: BridgeTokenTransfer]>;\n}\n\nexport class TokenBridge<\n TTezosBridgeBlockchainService extends TezosBridgeBlockchainService = TezosBridgeBlockchainService,\n TEtherlinkBridgeBlockchainService extends EtherlinkBridgeBlockchainService = EtherlinkBridgeBlockchainService\n> implements Disposable {\n private static readonly defaultLastCreatedTokenTransfersTimerPeriod = 60_000;\n private static readonly defaultLastCreatedTokenTransferLifetime = 30_000;\n\n readonly data: TokenBridgeDataApi;\n readonly stream: TokenBridgeStreamApi;\n readonly bridgeComponents: TokenBridgeComponents<TTezosBridgeBlockchainService, TEtherlinkBridgeBlockchainService>;\n\n protected readonly events: TokenBridgeComponentsEvents = {\n tokenTransferCreated: new EventEmitter(),\n tokenTransferUpdated: new EventEmitter()\n };\n\n protected readonly tokenTransferStatusWatchers = new Map<\n string,\n Map<BridgeTokenTransferStatus, {\n readonly promise: Promise<BridgeTokenTransfer>,\n readonly resolve: (transfer: BridgeTokenTransfer) => void,\n readonly reject: (error: unknown) => void\n }>\n >();\n\n private readonly lastCreatedTokenTransfers: Map<string, readonly [tokenTransfer: BridgeTokenTransfer, addedTime: number]> = new Map();\n private lastCreatedTokenTransfersTimerId: ReturnType<typeof setInterval> | undefined;\n private _isDisposed = false;\n\n constructor(options: TokenBridgeOptions<TTezosBridgeBlockchainService, TEtherlinkBridgeBlockchainService>) {\n this.bridgeComponents = {\n tezosBridgeBlockchainService: options.tezosBridgeBlockchainService,\n etherlinkBridgeBlockchainService: options.etherlinkBridgeBlockchainService,\n tokensBridgeDataProvider: options.bridgeDataProviders.tokens,\n balancesBridgeDataProvider: options.bridgeDataProviders.balances,\n transfersBridgeDataProvider: options.bridgeDataProviders.transfers\n };\n this.data = {\n getBalance: this.getBalance.bind(this),\n getBalances: this.getBalances.bind(this),\n getRegisteredTokenPair: this.getRegisteredTokenPair.bind(this),\n getRegisteredTokenPairs: this.getRegisteredTokenPairs.bind(this),\n getTokenTransfer: this.getTokenTransfer.bind(this),\n getTokenTransfers: this.getTokenTransfers.bind(this),\n getAccountTokenTransfers: this.getAccountTokenTransfers.bind(this),\n getOperationTokenTransfers: this.getOperationTokenTransfers.bind(this),\n getSignerBalances: this.getSignerBalances.bind(this),\n getSignerTokenTransfers: this.getSignerTokenTransfers.bind(this),\n };\n this.stream = {\n subscribeToTokenTransfer: this.subscribeToTokenTransfer.bind(this),\n subscribeToTokenTransfers: this.subscribeToTokenTransfers.bind(this),\n subscribeToAccountTokenTransfers: this.subscribeToAccountTokenTransfers.bind(this),\n subscribeToOperationTokenTransfers: this.subscribeToOperationTokenTransfers.bind(this),\n unsubscribeFromTokenTransfer: this.unsubscribeFromTokenTransfer.bind(this),\n unsubscribeFromTokenTransfers: this.unsubscribeFromTokenTransfers.bind(this),\n unsubscribeFromAccountTokenTransfers: this.unsubscribeFromAccountTokenTransfers.bind(this),\n unsubscribeFromOperationTokenTransfers: this.unsubscribeFromOperationTokenTransfers.bind(this),\n unsubscribeFromAllSubscriptions: this.unsubscribeFromAllSubscriptions.bind(this)\n };\n\n this.attachEvents();\n }\n\n get isDisposed() {\n return this._isDisposed;\n }\n\n addEventListener<EventType extends keyof TokenBridgeComponentsEvents>(\n type: EventType,\n listener: Parameters<TokenBridgeComponentsEvents[EventType]['addListener']>[0]\n ): void {\n this.ensureIsNotDisposed();\n this.events[type].addListener(listener as any);\n }\n\n removeEventListener<EventType extends keyof TokenBridgeComponentsEvents>(\n type: EventType,\n listener: Parameters<TokenBridgeComponentsEvents[EventType]['addListener']>[0]\n ): void {\n this.ensureIsNotDisposed();\n this.events[type].removeListener(listener as any);\n }\n\n removeAllEventListeners<EventType extends keyof TokenBridgeComponentsEvents>(type: EventType): void {\n this.ensureIsNotDisposed();\n this.events[type].removeAllListeners();\n }\n\n async waitForStatus(transfer: PendingBridgeTokenDeposit, status: BridgeTokenTransferStatus.Created): Promise<CreatedBridgeTokenDeposit>;\n async waitForStatus(transfer: PendingBridgeTokenDeposit | CreatedBridgeTokenDeposit, status: BridgeTokenTransferStatus.Finished): Promise<FinishedBridgeTokenDeposit>;\n async waitForStatus(transfer: PendingBridgeTokenWithdrawal, status: BridgeTokenTransferStatus.Created): Promise<CreatedBridgeTokenWithdrawal>;\n async waitForStatus(transfer: PendingBridgeTokenWithdrawal | CreatedBridgeTokenWithdrawal, status: BridgeTokenTransferStatus.Sealed): Promise<SealedBridgeTokenWithdrawal>;\n async waitForStatus(\n transfer: PendingBridgeTokenWithdrawal | CreatedBridgeTokenWithdrawal | SealedBridgeTokenWithdrawal,\n status: BridgeTokenTransferStatus.Finished\n ): Promise<FinishedBridgeTokenWithdrawal>;\n async waitForStatus(transfer: BridgeTokenTransfer, status: BridgeTokenTransferStatus): Promise<BridgeTokenTransfer>;\n async waitForStatus(transfer: BridgeTokenTransfer, status: BridgeTokenTransferStatus): Promise<BridgeTokenTransfer> {\n this.ensureIsNotDisposed();\n if (transfer.status >= status)\n return transfer;\n\n const isPending = transfer.status === BridgeTokenTransferStatus.Pending;\n const updatedTransfers = await (isPending\n ? this.bridgeComponents.transfersBridgeDataProvider.getOperationTokenTransfers(transfer)\n : this.bridgeComponents.transfersBridgeDataProvider.getTokenTransfer(transfer.id));\n const updatedTransfer = guards.isArray(updatedTransfers) ? updatedTransfers[0] : updatedTransfers;\n\n if (updatedTransfer?.status === status)\n return updatedTransfer;\n\n const statusWatcherKey = isPending ? bridgeUtils.getInitialOperation(transfer).hash : transfer.id;\n let statusWatchers = this.tokenTransferStatusWatchers.get(statusWatcherKey);\n if (!statusWatchers) {\n statusWatchers = new Map();\n this.tokenTransferStatusWatchers.set(statusWatcherKey, statusWatchers);\n }\n\n const watcher = statusWatchers.get(status);\n if (watcher)\n return watcher.promise;\n\n const watcherPromise = new Promise<BridgeTokenTransfer>((resolve, reject) => {\n const statusWatchers = this.tokenTransferStatusWatchers.get(statusWatcherKey);\n if (!statusWatchers) {\n reject(`Status watchers map not found for the ${statusWatcherKey} token transfer`);\n return;\n }\n\n setTimeout(() => {\n try {\n this.bridgeComponents.transfersBridgeDataProvider[isPending ? 'subscribeToOperationTokenTransfers' : 'subscribeToTokenTransfer'](statusWatcherKey);\n\n statusWatchers.set(status, {\n promise: watcherPromise,\n resolve: (updatedTransfer: BridgeTokenTransfer) => {\n this.bridgeComponents.transfersBridgeDataProvider[isPending ? 'unsubscribeFromOperationTokenTransfers' : 'unsubscribeFromTokenTransfer'](statusWatcherKey);\n resolve(updatedTransfer);\n },\n reject: (error: unknown) => {\n this.bridgeComponents.transfersBridgeDataProvider[isPending ? 'unsubscribeFromOperationTokenTransfers' : 'unsubscribeFromTokenTransfer'](statusWatcherKey);\n reject(error);\n }\n });\n }\n catch (error) {\n loggerProvider.logger.error(getErrorLogMessage(error));\n reject(error);\n }\n }, 0);\n });\n\n return watcherPromise;\n }\n\n async deposit(amount: bigint, token: NativeTezosToken): Promise<DepositResult<TTezosBridgeBlockchainService['depositNativeToken']>>;\n async deposit(amount: bigint, token: NativeTezosToken, etherlinkReceiverAddress: string): Promise<DepositResult<TTezosBridgeBlockchainService['depositNativeToken']>>;\n async deposit(amount: bigint, token: NativeTezosToken, options: DepositOptions): Promise<DepositResult<TTezosBridgeBlockchainService['depositNativeToken']>>;\n async deposit(amount: bigint, token: NativeTezosToken, etherlinkReceiverAddress: string, options: DepositOptions): Promise<DepositResult<TTezosBridgeBlockchainService['depositNativeToken']>>;\n async deposit(amount: bigint, token: NonNativeTezosToken): Promise<DepositResult<TTezosBridgeBlockchainService['depositNonNativeToken']>>;\n async deposit(amount: bigint, token: NonNativeTezosToken, etherlinkReceiverAddress: string): Promise<DepositResult<TTezosBridgeBlockchainService['depositNonNativeToken']>>;\n async deposit(amount: bigint, token: NonNativeTezosToken, options: DepositOptions): Promise<DepositResult<TTezosBridgeBlockchainService['depositNonNativeToken']>>;\n async deposit(amount: bigint, token: NonNativeTezosToken, etherlinkReceiverAddress: string, options: DepositOptions): Promise<DepositResult<TTezosBridgeBlockchainService['depositNonNativeToken']>>;\n async deposit(\n amount: bigint,\n token: TezosToken,\n etherlinkReceiverAddressOrOptions?: string | DepositOptions,\n options?: DepositOptions\n ): Promise<DepositResult<TTezosBridgeBlockchainService['depositNativeToken']> | DepositResult<TTezosBridgeBlockchainService['depositNonNativeToken']>>;\n async deposit(\n amount: bigint,\n token: TezosToken,\n etherlinkReceiverAddressOrOptions?: string | DepositOptions,\n options?: DepositOptions\n ): Promise<DepositResult<TTezosBridgeBlockchainService['depositNativeToken']> | DepositResult<TTezosBridgeBlockchainService['depositNonNativeToken']>> {\n this.ensureIsNotDisposed();\n\n const tezosSourceAddress = await this.getRequiredTezosSignerAddress();\n const etherlinkReceiverAddress = typeof etherlinkReceiverAddressOrOptions === 'string'\n ? etherlinkReceiverAddressOrOptions\n : await this.getRequiredEtherlinkSignerAddress();\n const depositOptions = typeof etherlinkReceiverAddressOrOptions !== 'string' && etherlinkReceiverAddressOrOptions ? etherlinkReceiverAddressOrOptions : options;\n\n loggerProvider.lazyLogger.log?.(\n `Depositing ${amount.toString(10)} ${getTokenLogMessage(token)} from ${tezosSourceAddress} to ${etherlinkReceiverAddress}`\n );\n\n const tokenPair = await this.bridgeComponents.tokensBridgeDataProvider.getRegisteredTokenPair(token);\n if (!tokenPair) {\n const error = new TokenPairNotFoundError(token);\n loggerProvider.logger.error(getErrorLogMessage(error));\n throw error;\n }\n const accountTokenBalance = await this.bridgeComponents.balancesBridgeDataProvider.getBalance(tezosSourceAddress, token);\n if (amount > accountTokenBalance.balance) {\n const error = new InsufficientBalanceError(token, tezosSourceAddress, accountTokenBalance.balance, amount);\n loggerProvider.logger.error(getErrorLogMessage(error));\n throw error;\n }\n loggerProvider.logger.log(`The ${tezosSourceAddress} has enough tokens to deposit ${amount}`);\n\n const operationResult = await (token.type === 'native'\n ? this.bridgeComponents.tezosBridgeBlockchainService.depositNativeToken({\n amount,\n etherlinkReceiverAddress,\n ticketHelperContractAddress: tokenPair.tezos.ticketHelperContractAddress,\n })\n : this.bridgeComponents.tezosBridgeBlockchainService.depositNonNativeToken({\n token,\n amount,\n etherlinkReceiverAddress,\n ticketHelperContractAddress: tokenPair.tezos.ticketHelperContractAddress,\n useApprove: depositOptions?.useApprove,\n resetFA12Approve: depositOptions?.resetFA12Approve,\n })\n );\n loggerProvider.logger.log('The deposit operation has been created:', operationResult.hash);\n\n const tokenTransfer: PendingBridgeTokenDeposit = {\n kind: BridgeTokenTransferKind.Deposit,\n status: BridgeTokenTransferStatus.Pending,\n source: tezosSourceAddress,\n receiver: etherlinkReceiverAddress,\n tezosOperation: {\n hash: operationResult.hash,\n amount: operationResult.amount,\n timestamp: operationResult.timestamp,\n token,\n }\n };\n\n loggerProvider.lazyLogger.log?.(getBridgeTokenTransferLogMessage(tokenTransfer));\n loggerProvider.lazyLogger.debug?.(getDetailedBridgeTokenTransferLogMessage(tokenTransfer));\n\n this.emitLocalTokenTransferCreatedEvent(tokenTransfer);\n\n return {\n tokenTransfer,\n operationResult\n } as DepositResult<TTezosBridgeBlockchainService['depositNativeToken']> | DepositResult<TTezosBridgeBlockchainService['depositNonNativeToken']>;\n }\n\n async startWithdraw(\n amount: bigint,\n token: NativeEtherlinkToken,\n tezosReceiverAddress?: string\n ): Promise<StartWithdrawResult<TEtherlinkBridgeBlockchainService['withdrawNativeToken']>>;\n async startWithdraw(\n amount: bigint,\n token: NonNativeEtherlinkToken,\n tezosReceiverAddress?: string\n ): Promise<StartWithdrawResult<TEtherlinkBridgeBlockchainService['withdrawNonNativeToken']>>;\n async startWithdraw(\n amount: bigint,\n token: EtherlinkToken,\n tezosReceiverAddress?: string\n ): Promise<StartWithdrawResult<TEtherlinkBridgeBlockchainService['withdrawNativeToken']> | StartWithdrawResult<TEtherlinkBridgeBlockchainService['withdrawNonNativeToken']>>;\n async startWithdraw(\n amount: bigint,\n token: EtherlinkToken,\n tezosReceiverAddress?: string\n ): Promise<StartWithdrawResult<TEtherlinkBridgeBlockchainService['withdrawNativeToken']> | StartWithdrawResult<TEtherlinkBridgeBlockchainService['withdrawNonNativeToken']>> {\n this.ensureIsNotDisposed();\n\n const etherlinkSourceAddress = await this.getRequiredEtherlinkSignerAddress();\n if (!tezosReceiverAddress) {\n tezosReceiverAddress = await this.getRequiredTezosSignerAddress();\n }\n\n const tokenPair = await this.bridgeComponents.tokensBridgeDataProvider.getRegisteredTokenPair(token);\n if (!tokenPair) {\n const error = new TokenPairNotFoundError(token);\n loggerProvider.logger.error(getErrorLogMessage(error));\n throw error;\n }\n const accountTokenBalance = await this.bridgeComponents.balancesBridgeDataProvider.getBalance(etherlinkSourceAddress, token);\n if (amount > accountTokenBalance.balance) {\n const error = new InsufficientBalanceError(token, etherlinkSourceAddress, accountTokenBalance.balance, amount);\n loggerProvider.logger.error(getErrorLogMessage(error));\n throw error;\n }\n loggerProvider.logger.log(`The ${etherlinkSourceAddress} has enough tokens to withdraw ${amount}`);\n\n let operationResult: Awaited<ReturnType<typeof this.startWithdraw>>['operationResult'];\n if (tokenPair.tezos.type === 'native') {\n operationResult = (await this.bridgeComponents.etherlinkBri