-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Sign, send and track transactions (#21)
* Add transactions tracking
- Loading branch information
1 parent
333db0b
commit b89cc1e
Showing
59 changed files
with
1,833 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import axios from 'axios'; | ||
import { TRANSACTIONS_ENDPOINT } from 'apiCalls/endpoints'; | ||
import { getState } from 'store/store'; | ||
import { networkSelector } from 'store/selectors'; | ||
import { ServerTransactionType } from 'types/serverTransactions.types'; | ||
|
||
export const getTransactionByHash = (hash: string) => { | ||
const { apiAddress } = networkSelector(getState()); | ||
|
||
return axios.get<ServerTransactionType>( | ||
`${apiAddress}/${TRANSACTIONS_ENDPOINT}/${hash}`, | ||
{ | ||
timeout: 10000 // 10sec | ||
} | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import axios from 'axios'; | ||
import { TRANSACTIONS_ENDPOINT } from 'apiCalls/endpoints'; | ||
|
||
import { getState } from 'store/store'; | ||
import { networkSelector } from 'store/selectors'; | ||
import { | ||
GetTransactionsByHashesReturnType, | ||
PendingTransactionsType | ||
} from 'types/transactions.types'; | ||
|
||
export const getTransactionsByHashes = async ( | ||
pendingTransactions: PendingTransactionsType | ||
): Promise<GetTransactionsByHashesReturnType> => { | ||
const { apiAddress } = networkSelector(getState()); | ||
const hashes = pendingTransactions.map((tx) => tx.hash); | ||
|
||
const { data: responseData } = await axios.get( | ||
`${apiAddress}/${TRANSACTIONS_ENDPOINT}`, | ||
{ | ||
params: { | ||
hashes: hashes.join(','), | ||
withScResults: true | ||
} | ||
} | ||
); | ||
|
||
return pendingTransactions.map(({ hash, previousStatus }) => { | ||
const txOnNetwork = responseData.find( | ||
(txResponse: any) => txResponse?.txHash === hash | ||
); | ||
|
||
return { | ||
hash, | ||
data: txOnNetwork?.data, | ||
invalidTransaction: txOnNetwork == null, | ||
status: txOnNetwork?.status, | ||
results: txOnNetwork?.results, | ||
sender: txOnNetwork?.sender, | ||
receiver: txOnNetwork?.receiver, | ||
previousStatus, | ||
hasStatusChanged: txOnNetwork && txOnNetwork.status !== previousStatus | ||
}; | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import axios from 'axios'; | ||
|
||
export async function getWebsocketUrl(apiAddress: string) { | ||
try { | ||
const { data } = await axios.get<{ url: string }>( | ||
`${apiAddress}/websocket/config` | ||
); | ||
return `wss://${data.url}`; | ||
} catch (err) { | ||
console.error(err); | ||
throw new Error('Can not get websocket url'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './getWebsocketUrl'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export const GAS_PRICE_MODIFIER = 0.01; | ||
export const GAS_PER_DATA_BYTE = 1500; | ||
export const GAS_LIMIT = 50000; | ||
/** | ||
* Extra gas limit for guarded transactions | ||
*/ | ||
export const EXTRA_GAS_LIMIT_GUARDED_TX = 50000; | ||
export const GAS_PRICE = 1000000000; | ||
export const DECIMALS = 18; | ||
export const DIGITS = 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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export const CANCEL_TRANSACTION_TOAST_ID = 'cancel-transaction-toast'; | ||
export const AVERAGE_TX_DURATION_MS = 6000; | ||
export const CROSS_SHARD_ROUNDS = 5; | ||
export const TRANSACTIONS_STATUS_POLLING_INTERVAL_MS = 90 * 1000; // 90sec | ||
export const TRANSACTIONS_STATUS_DROP_INTERVAL_MS = 10 * 60 * 1000; // 10min | ||
export const CANCEL_TRANSACTION_TOAST_DEFAULT_DURATION = 20000; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import { accountSelector } from 'store/selectors'; | ||
import { getState } from 'store/store'; | ||
|
||
export function getAccount() { | ||
return accountSelector(getState()); | ||
export function getAccount(state = getState()) { | ||
return accountSelector(state); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
src/core/methods/initApp/websocket/initializeWebsocketConnection.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import { io } from 'socket.io-client'; | ||
import { retryMultipleTimes } from 'utils/retryMultipleTimes'; | ||
import { | ||
BatchTransactionsWSResponseType, | ||
websocketConnection, | ||
WebsocketConnectionStatusEnum | ||
} from './websocket.constants'; | ||
import { getWebsocketUrl } from 'apiCalls/websocket'; | ||
import { getStore } from 'store/store'; | ||
import { getAccount } from 'core/methods/account/getAccount'; | ||
import { networkSelector } from 'store/selectors'; | ||
import { | ||
setWebsocketBatchEvent, | ||
setWebsocketEvent | ||
} from 'store/actions/account/accountActions'; | ||
|
||
const TIMEOUT = 3000; | ||
const RECONNECTION_ATTEMPTS = 3; | ||
const RETRY_INTERVAL = 500; | ||
const MESSAGE_DELAY = 1000; | ||
const BATCH_UPDATED_EVENT = 'batchUpdated'; | ||
const CONNECT = 'connect'; | ||
const DISCONNECT = 'disconnect'; | ||
|
||
export async function initializeWebsocketConnection() { | ||
const { address } = getAccount(); | ||
const { apiAddress } = networkSelector(getStore().getState()); | ||
|
||
let messageTimeout: NodeJS.Timeout | null = null; | ||
let batchTimeout: NodeJS.Timeout | null = null; | ||
|
||
const handleMessageReceived = (message: string) => { | ||
if (messageTimeout) { | ||
clearTimeout(messageTimeout); | ||
} | ||
messageTimeout = setTimeout(() => { | ||
setWebsocketEvent(message); | ||
}, MESSAGE_DELAY); | ||
}; | ||
|
||
const handleBatchUpdate = (data: BatchTransactionsWSResponseType) => { | ||
if (batchTimeout) { | ||
clearTimeout(batchTimeout); | ||
} | ||
batchTimeout = setTimeout(() => { | ||
setWebsocketBatchEvent(data); | ||
}, MESSAGE_DELAY); | ||
}; | ||
|
||
const initializeConnection = retryMultipleTimes( | ||
async () => { | ||
// To avoid multiple connections to the same endpoint | ||
websocketConnection.status = WebsocketConnectionStatusEnum.PENDING; | ||
|
||
const websocketUrl = await getWebsocketUrl(apiAddress); | ||
|
||
if (!websocketUrl) { | ||
console.warn('Cannot get websocket URL'); | ||
return; | ||
} | ||
|
||
websocketConnection.instance = io(websocketUrl, { | ||
forceNew: true, | ||
reconnectionAttempts: RECONNECTION_ATTEMPTS, | ||
timeout: TIMEOUT, | ||
query: { address } | ||
}); | ||
|
||
websocketConnection.status = WebsocketConnectionStatusEnum.COMPLETED; | ||
|
||
websocketConnection.instance.onAny(handleMessageReceived); | ||
|
||
websocketConnection.instance.on(BATCH_UPDATED_EVENT, handleBatchUpdate); | ||
|
||
websocketConnection.instance.on(CONNECT, () => { | ||
console.log('Websocket connected.'); | ||
}); | ||
|
||
websocketConnection.instance.on(DISCONNECT, () => { | ||
console.warn('Websocket disconnected. Trying to reconnect...'); | ||
setTimeout(() => { | ||
console.log('Websocket reconnecting...'); | ||
websocketConnection.instance?.connect(); | ||
}, RETRY_INTERVAL); | ||
}); | ||
}, | ||
{ retries: 2, delay: RETRY_INTERVAL } | ||
); | ||
|
||
const closeConnection = () => { | ||
websocketConnection.instance?.close(); | ||
websocketConnection.status = WebsocketConnectionStatusEnum.NOT_INITIALIZED; | ||
if (messageTimeout) { | ||
clearTimeout(messageTimeout); | ||
} | ||
if (batchTimeout) { | ||
clearTimeout(batchTimeout); | ||
} | ||
}; | ||
|
||
if ( | ||
address && | ||
websocketConnection.status === | ||
WebsocketConnectionStatusEnum.NOT_INITIALIZED && | ||
!websocketConnection.instance?.active | ||
) { | ||
await initializeConnection(); | ||
} | ||
|
||
return { | ||
closeConnection | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { initializeWebsocketConnection } from './initializeWebsocketConnection'; | ||
import { getStore } from 'store/store'; | ||
import { getAccount } from 'core/methods/account/getAccount'; | ||
|
||
let localAddress = ''; | ||
let closeConnectionRef: () => void; | ||
|
||
export const registerWebsocketListener = async () => { | ||
const store = getStore(); | ||
const account = getAccount(); | ||
localAddress = account.address; | ||
|
||
// Initialize the websocket connection | ||
const data = await initializeWebsocketConnection(); | ||
closeConnectionRef = data.closeConnection; | ||
|
||
store.subscribe(async ({ account: { address } }) => { | ||
if (localAddress && address !== localAddress) { | ||
closeConnectionRef(); | ||
localAddress = address; | ||
const { closeConnection } = await initializeWebsocketConnection(); | ||
closeConnectionRef = closeConnection; | ||
} | ||
}); | ||
}; |
Oops, something went wrong.