-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add a new Passport config option to automatically request a tra…
…nsaction when SCW is not deployed (#2149) Co-authored-by: Hayden Fowler <hayden.fowler@gmail.com>
- Loading branch information
1 parent
52c855b
commit 1e9b20b
Showing
10 changed files
with
819 additions
and
361 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
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
164 changes: 164 additions & 0 deletions
164
packages/passport/sdk/src/zkEvm/sendDeployTransactionAndPersonalSign.test.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,164 @@ | ||
import { StaticJsonRpcProvider } from '@ethersproject/providers'; | ||
import { Signer } from '@ethersproject/abstract-signer'; | ||
import { Flow } from '@imtbl/metrics'; | ||
import { BigNumber } from 'ethers'; | ||
import { sendDeployTransactionAndPersonalSign } from './sendDeployTransactionAndPersonalSign'; | ||
import { mockUserZkEvm } from '../test/mocks'; | ||
import { RelayerClient } from './relayerClient'; | ||
import GuardianClient from '../guardian'; | ||
import * as transactionHelpers from './transactionHelpers'; | ||
import * as personalSign from './personalSign'; | ||
|
||
jest.mock('./transactionHelpers'); | ||
jest.mock('./personalSign'); | ||
|
||
describe('sendDeployTransactionAndPersonalSign', () => { | ||
const signedTransactions = 'signedTransactions123'; | ||
const relayerTransactionId = 'relayerTransactionId123'; | ||
const transactionHash = 'transactionHash123'; | ||
const signedMessage = 'signedMessage123'; | ||
|
||
const nonce = BigNumber.from(5); | ||
|
||
const params = ['message to sign']; | ||
const rpcProvider = { | ||
detectNetwork: jest.fn(), | ||
}; | ||
const relayerClient = { | ||
imGetFeeOptions: jest.fn(), | ||
ethSendTransaction: jest.fn(), | ||
imGetTransactionByHash: jest.fn(), | ||
}; | ||
const guardianClient = { | ||
validateEVMTransaction: jest.fn(), | ||
withConfirmationScreen: jest.fn(), | ||
}; | ||
const ethSigner = { | ||
getAddress: jest.fn(), | ||
} as Partial<Signer> as Signer; | ||
const flow = { | ||
addEvent: jest.fn(), | ||
}; | ||
|
||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
(transactionHelpers.prepareAndSignTransaction as jest.Mock).mockResolvedValue({ | ||
signedTransactions, | ||
relayerId: relayerTransactionId, | ||
nonce, | ||
}); | ||
(transactionHelpers.pollRelayerTransaction as jest.Mock).mockResolvedValue({ | ||
hash: transactionHash, | ||
}); | ||
(personalSign.personalSign as jest.Mock).mockResolvedValue(signedMessage); | ||
(guardianClient.withConfirmationScreen as jest.Mock) | ||
.mockImplementation(() => (task: () => void) => task()); | ||
}); | ||
|
||
it('calls prepareAndSignTransaction with the correct arguments', async () => { | ||
await sendDeployTransactionAndPersonalSign({ | ||
params, | ||
ethSigner, | ||
rpcProvider: rpcProvider as unknown as StaticJsonRpcProvider, | ||
relayerClient: relayerClient as unknown as RelayerClient, | ||
zkEvmAddress: mockUserZkEvm.zkEvm.ethAddress, | ||
guardianClient: guardianClient as unknown as GuardianClient, | ||
flow: flow as unknown as Flow, | ||
}); | ||
|
||
expect(transactionHelpers.prepareAndSignTransaction).toHaveBeenCalledWith({ | ||
transactionRequest: { to: mockUserZkEvm.zkEvm.ethAddress, value: 0 }, | ||
ethSigner, | ||
rpcProvider: rpcProvider as unknown as StaticJsonRpcProvider, | ||
relayerClient: relayerClient as unknown as RelayerClient, | ||
guardianClient: guardianClient as unknown as GuardianClient, | ||
zkEvmAddress: mockUserZkEvm.zkEvm.ethAddress, | ||
flow: flow as unknown as Flow, | ||
}); | ||
}); | ||
|
||
it('calls personalSign with the correct arguments', async () => { | ||
await sendDeployTransactionAndPersonalSign({ | ||
params, | ||
ethSigner, | ||
rpcProvider: rpcProvider as unknown as StaticJsonRpcProvider, | ||
relayerClient: relayerClient as unknown as RelayerClient, | ||
zkEvmAddress: mockUserZkEvm.zkEvm.ethAddress, | ||
guardianClient: guardianClient as unknown as GuardianClient, | ||
flow: flow as unknown as Flow, | ||
}); | ||
|
||
expect(personalSign.personalSign).toHaveBeenCalledWith({ | ||
params, | ||
ethSigner, | ||
zkEvmAddress: mockUserZkEvm.zkEvm.ethAddress, | ||
rpcProvider: rpcProvider as unknown as StaticJsonRpcProvider, | ||
guardianClient: guardianClient as unknown as GuardianClient, | ||
relayerClient: relayerClient as unknown as RelayerClient, | ||
flow: flow as unknown as Flow, | ||
}); | ||
}); | ||
|
||
it('calls pollRelayerTransaction with the correct arguments', async () => { | ||
await sendDeployTransactionAndPersonalSign({ | ||
params, | ||
ethSigner, | ||
rpcProvider: rpcProvider as unknown as StaticJsonRpcProvider, | ||
relayerClient: relayerClient as unknown as RelayerClient, | ||
zkEvmAddress: mockUserZkEvm.zkEvm.ethAddress, | ||
guardianClient: guardianClient as unknown as GuardianClient, | ||
flow: flow as unknown as Flow, | ||
}); | ||
|
||
expect(transactionHelpers.pollRelayerTransaction).toHaveBeenCalledWith( | ||
relayerClient as unknown as RelayerClient, | ||
relayerTransactionId, | ||
flow as unknown as Flow, | ||
); | ||
}); | ||
|
||
it('returns the signed message', async () => { | ||
const result = await sendDeployTransactionAndPersonalSign({ | ||
params, | ||
ethSigner, | ||
rpcProvider: rpcProvider as unknown as StaticJsonRpcProvider, | ||
relayerClient: relayerClient as unknown as RelayerClient, | ||
zkEvmAddress: mockUserZkEvm.zkEvm.ethAddress, | ||
guardianClient: guardianClient as unknown as GuardianClient, | ||
flow: flow as unknown as Flow, | ||
}); | ||
|
||
expect(result).toEqual(signedMessage); | ||
}); | ||
|
||
it('calls guardianClient.withConfirmationScreen with the correct arguments', async () => { | ||
await sendDeployTransactionAndPersonalSign({ | ||
params, | ||
ethSigner, | ||
rpcProvider: rpcProvider as unknown as StaticJsonRpcProvider, | ||
relayerClient: relayerClient as unknown as RelayerClient, | ||
zkEvmAddress: mockUserZkEvm.zkEvm.ethAddress, | ||
guardianClient: guardianClient as unknown as GuardianClient, | ||
flow: flow as unknown as Flow, | ||
}); | ||
|
||
expect(guardianClient.withConfirmationScreen).toHaveBeenCalled(); | ||
}); | ||
|
||
it('throws an error if any step fails', async () => { | ||
const error = new Error('Something went wrong'); | ||
(transactionHelpers.prepareAndSignTransaction as jest.Mock).mockRejectedValue(error); | ||
|
||
await expect( | ||
sendDeployTransactionAndPersonalSign({ | ||
params, | ||
ethSigner, | ||
rpcProvider: rpcProvider as unknown as StaticJsonRpcProvider, | ||
relayerClient: relayerClient as unknown as RelayerClient, | ||
zkEvmAddress: mockUserZkEvm.zkEvm.ethAddress, | ||
guardianClient: guardianClient as unknown as GuardianClient, | ||
flow: flow as unknown as Flow, | ||
}), | ||
).rejects.toThrow(error); | ||
}); | ||
}); |
44 changes: 44 additions & 0 deletions
44
packages/passport/sdk/src/zkEvm/sendDeployTransactionAndPersonalSign.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,44 @@ | ||
import { prepareAndSignTransaction, pollRelayerTransaction, TransactionParams } from './transactionHelpers'; | ||
import { personalSign } from './personalSign'; | ||
|
||
type EthSendDeployTransactionParams = TransactionParams & { | ||
params: Array<any>; | ||
}; | ||
|
||
export const sendDeployTransactionAndPersonalSign = async ({ | ||
params, | ||
ethSigner, | ||
rpcProvider, | ||
relayerClient, | ||
guardianClient, | ||
zkEvmAddress, | ||
flow, | ||
}: EthSendDeployTransactionParams): Promise<string> => { | ||
const deployTransaction = { to: zkEvmAddress, value: 0 }; | ||
|
||
const { relayerId } = await prepareAndSignTransaction({ | ||
transactionRequest: deployTransaction, | ||
ethSigner, | ||
rpcProvider, | ||
guardianClient, | ||
relayerClient, | ||
zkEvmAddress, | ||
flow, | ||
}); | ||
|
||
return guardianClient.withConfirmationScreen()(async () => { | ||
const signedMessage = await personalSign({ | ||
params, | ||
ethSigner, | ||
zkEvmAddress, | ||
rpcProvider, | ||
guardianClient, | ||
relayerClient, | ||
flow, | ||
}); | ||
|
||
await pollRelayerTransaction(relayerClient, relayerId, flow); | ||
|
||
return signedMessage; | ||
}); | ||
}; |
Oops, something went wrong.