Last active
July 10, 2023 20:54
-
-
Save ankushswar1/a84ff7338761839d23e8b4a0ed1db1fd to your computer and use it in GitHub Desktop.
ReservoirWallet adapter using Gelato Relayer
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
import type { ReservoirWallet } from '@reservoir0x/reservoir-sdk'; | |
import { GelatoRelay } from "@gelatonetwork/relay-sdk"; | |
import { arrayify } from 'ethers/lib/utils'; | |
import type { Web3Provider } from '@ethersproject/providers'; | |
import type { TypedDataSigner } from '@ethersproject/abstract-signer/lib/index'; | |
const sleep = (time: number) => new Promise((resolve) => setTimeout(resolve, time)); | |
const getTaskStatus = async (taskId: string) => { | |
let taskState; | |
const terminalStates = ['ExecReverted', 'Cancelled', 'ExecSuccess']; | |
do { | |
const response = await fetch(`https://api.gelato.digital/tasks/status/${taskId}`); | |
const status = await response.json(); | |
taskState = status.task.taskState; | |
if (taskState === 'ExecSuccess') { | |
// Success case - return transaction hash | |
return status.task.transactionHash; | |
} else if (taskState === 'ExecReverted' || taskState === 'Cancelled') { | |
// Error case - return undefined | |
return; | |
} else { | |
await sleep(3000); | |
} | |
} while (!terminalStates.includes(taskState)); | |
} | |
export const getGelatoAdapter = (provider: Web3Provider): ReservoirWallet => { | |
return { | |
// https://github.com/reservoirprotocol/reservoir-kit/blob/main/packages/ethers-wallet-adapter/src/adapter.ts | |
address: async () => { | |
const signer = await provider.getSigner(); | |
return signer.getAddress() | |
}, | |
// https://github.com/reservoirprotocol/reservoir-kit/blob/main/packages/ethers-wallet-adapter/src/adapter.ts | |
handleSignMessageStep: async (stepItem) => { | |
const signer = await provider.getSigner(); | |
const signData = stepItem.data?.sign | |
let signature: string | undefined | |
if (signData) { | |
// Request user signature | |
if (signData.signatureKind === 'eip191') { | |
if (signData.message.match(/0x[0-9a-fA-F]{64}/)) { | |
// If the message represents a hash, we need to convert it to raw bytes first | |
signature = await signer.signMessage(arrayify(signData.message)) | |
} else { | |
signature = await signer.signMessage(signData.message) | |
} | |
} else if (signData.signatureKind === 'eip712') { | |
signature = await ( | |
signer as unknown as TypedDataSigner | |
)._signTypedData(signData.domain, signData.types, signData.value) | |
} | |
} | |
return signature | |
}, | |
handleSendTransactionStep: async (chainId, stepItem) => { | |
const { gas, ...stepData } = stepItem.data; | |
const signer = await provider.getSigner(); | |
const address = await signer.getAddress(); | |
const relay = new GelatoRelay(); | |
const request = { | |
chainId: chainId, | |
target: stepData.to, | |
data: stepData.data, | |
user: address | |
}; | |
const relayResponse = await relay.sponsoredCallERC2771(request, provider, process.env.NEXT_PUBLIC_GELATO_API_KEY as string); | |
const {taskId} = relayResponse; | |
const txHash = await getTaskStatus(taskId); | |
// Poll status of relayResponse.taskId and return transaction hash | |
return txHash; | |
}, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment