Skip to content

Commit

Permalink
fix: single loop to query relay wallet responses
Browse files Browse the repository at this point in the history
  • Loading branch information
dawidsowardx committed Sep 18, 2024
1 parent 42b044f commit d4b5cc6
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type PartitionKey =
| 'requests'
| 'state'
| 'connectButton'
| 'walletResponses'
| 'connectorExtension'
type dAppDefinitionAddress = string

Expand Down Expand Up @@ -71,6 +72,11 @@ export const LocalStorageModule = <T extends object = any>(
: err(new Error('Item not found'))
})

/**
* Merge items with the existing items in the storage
* @param item
* @returns
*/
const setItems = (item: Record<string, T>): ResultAsync<void, Error> =>
getItems().andThen((data) =>
stringify({ ...data, ...item }).asyncAndThen((serialized) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ResultAsync, err, errAsync, ok } from 'neverthrow'
import { ResultAsync, err, errAsync, ok, okAsync } from 'neverthrow'
import { Subscription } from 'rxjs'
import { EncryptionModule, transformBufferToSealbox } from '../../encryption'
import { Session, SessionModule } from '../../session/session.module'
Expand Down Expand Up @@ -40,6 +40,8 @@ export const RadixConnectRelayModule = (input: {
const { baseUrl, providers, walletUrl } = input
const { requestItemModule, storageModule } = providers

const walletResponses = storageModule.getPartition('walletResponses')

const encryptionModule = providers?.encryptionModule ?? EncryptionModule()

const deepLinkModule =
Expand Down Expand Up @@ -75,6 +77,58 @@ export const RadixConnectRelayModule = (input: {

const subscriptions = new Subscription()

const wait = (timer = 1800) =>
new Promise((resolve) => setTimeout(resolve, timer))

const decryptWalletResponse = (
walletResponse: WalletResponse,
): ResultAsync<WalletInteractionResponse, { reason: string }> => {
if ('error' in walletResponse) {
return errAsync({ reason: walletResponse.error })
}

return identityModule.get('dApp').andThen((dAppIdentity) =>
dAppIdentity.x25519
.calculateSharedSecret(
walletResponse.publicKey,
input.dAppDefinitionAddress,
)
.mapErr(() => ({ reason: 'FailedToDeriveSharedSecret' }))
.asyncAndThen((sharedSecret) =>
decryptWalletResponseData(sharedSecret, walletResponse.data),
),
)
}

const checkRelayLoop = async () => {
await requestItemModule.getPending().andThen((pendingItems) => {
if (pendingItems.length === 0) {
return okAsync(undefined)
}

return sessionModule
.getCurrentSession()
.andThen((session) =>
radixConnectRelayApiService.getResponses(session.sessionId),
)
.andThen((responses) =>
ResultAsync.combine(
responses.map((response) =>
decryptWalletResponse(response).andThen((decryptedResponse) =>
walletResponses.setItems({
[decryptedResponse.interactionId]: decryptedResponse,
}),
),
),
),
)
})
await wait()
checkRelayLoop()
}

checkRelayLoop()

const sendWalletInteractionRequest = ({
session,
walletInteraction,
Expand Down Expand Up @@ -156,13 +210,7 @@ export const RadixConnectRelayModule = (input: {
publicKey: dAppIdentity.x25519.getPublicKey(),
}),
)
.andThen(() =>
waitForWalletResponse({
session,
interactionId: walletInteraction.interactionId,
dAppIdentity,
}),
),
.andThen(() => waitForWalletResponse(walletInteraction.interactionId)),
)

const decryptWalletResponseData = (
Expand All @@ -188,50 +236,19 @@ export const RadixConnectRelayModule = (input: {
jsError: error,
}))

const waitForWalletResponse = ({
session,
interactionId,
dAppIdentity,
}: {
session: Session
interactionId: string
dAppIdentity: Curve25519
}): ResultAsync<WalletInteractionResponse, SdkError> =>
const waitForWalletResponse = (
interactionId: string,
): ResultAsync<WalletInteractionResponse, SdkError> =>
ResultAsync.fromPromise(
new Promise(async (resolve, reject) => {
let response: WalletInteractionResponse | undefined
let error: SdkError | undefined
let retry = 0

const wait = (timer = 1500) =>
new Promise((resolve) => setTimeout(resolve, timer))

logger?.debug({
method: 'waitForWalletResponse',
sessionId: session.sessionId,
interactionId,
})

const getEncryptedWalletResponses = () =>
radixConnectRelayApiService.getResponses(session.sessionId)

const decryptWalletResponse = (
walletResponse: WalletResponse,
): ResultAsync<WalletInteractionResponse, { reason: string }> => {
if ('error' in walletResponse) {
return errAsync({ reason: walletResponse.error })
}
return dAppIdentity.x25519
.calculateSharedSecret(
walletResponse.publicKey,
input.dAppDefinitionAddress,
)
.mapErr(() => ({ reason: 'FailedToDeriveSharedSecret' }))
.asyncAndThen((sharedSecret) =>
decryptWalletResponseData(sharedSecret, walletResponse.data),
)
}

while (!response) {
const requestItemResult =
await requestItemModule.getById(interactionId)
Expand All @@ -251,41 +268,20 @@ export const RadixConnectRelayModule = (input: {
}
}

const encryptedWalletResponsesResult =
await getEncryptedWalletResponses()

if (encryptedWalletResponsesResult.isOk()) {
const encryptedWalletResponses =
encryptedWalletResponsesResult.value

for (const encryptedWalletResponse of encryptedWalletResponses) {
const walletResponseResult = await decryptWalletResponse(
encryptedWalletResponse,
)

if (walletResponseResult.isErr())
logger?.error({
method: 'waitForWalletResponse.decryptWalletResponse.error',
error: walletResponseResult.error,
sessionId: session.sessionId,
interactionId,
})

if (walletResponseResult.isOk()) {
const walletResponse = walletResponseResult.value
const walletResponse =
await walletResponses.getItemById(interactionId)

if (walletResponse.interactionId === interactionId) {
response = walletResponse
await requestItemModule.patch(walletResponse.interactionId, {
walletResponse,
})
}
}
if (walletResponse.isOk()) {
if (walletResponse.value) {
response = walletResponse.value
await requestItemModule.patch(interactionId, {
walletResponse: walletResponse.value,
})
await walletResponses.removeItemById(interactionId)
}
}

if (!response) {
retry += 1
await wait()
}
}
Expand Down

0 comments on commit d4b5cc6

Please sign in to comment.