diff --git a/.github/workflows/pr-release.yaml b/.github/workflows/pr-release.yaml index 3b36f8e0..9b23cd55 100644 --- a/.github/workflows/pr-release.yaml +++ b/.github/workflows/pr-release.yaml @@ -27,6 +27,7 @@ jobs: - name: Build run: pnpm build + env: NEXT_PUBLIC_PROVIDER_URL: "http://localhost:4000/v1/graphql" NEXT_PUBLIC_WC_PROJECT_ID: e01471314fc69cc4efba6dce12dfd710 NEXT_PUBLIC_CHAIN_ID_NAME: testnet diff --git a/packages/burner-wallet-connector/src/BurnerWalletConnector.ts b/packages/burner-wallet-connector/src/BurnerWalletConnector.ts index 90838f1f..0301ffcc 100644 --- a/packages/burner-wallet-connector/src/BurnerWalletConnector.ts +++ b/packages/burner-wallet-connector/src/BurnerWalletConnector.ts @@ -230,6 +230,21 @@ export class BurnerWalletConnector extends FuelConnector { return transactionRequest.id; } + async signTransaction( + _address: string, + _transaction: TransactionRequestLike, + ): Promise { + if (!this.burnerWallet) { + throw Error('Wallet not connected'); + } + + if (_address !== this.burnerWallet.address.toString()) { + throw Error('Address not found for the connector'); + } + + return this.burnerWallet.signTransaction(_transaction); + } + async currentAccount(): Promise { if (!this.burnerWallet) { throw Error('Wallet not connected'); diff --git a/packages/burner-wallet-connector/src/tests/burnerWalletConnector.test.ts b/packages/burner-wallet-connector/src/tests/burnerWalletConnector.test.ts index d8b23f69..d3eb62c2 100644 --- a/packages/burner-wallet-connector/src/tests/burnerWalletConnector.test.ts +++ b/packages/burner-wallet-connector/src/tests/burnerWalletConnector.test.ts @@ -1,5 +1,12 @@ import path from 'node:path'; -import { type Asset, type Network, Provider, Wallet } from 'fuels'; +import { + type Asset, + type Network, + Provider, + Signer, + Wallet, + getRandomB256, +} from 'fuels'; import { launchTestNode } from 'fuels/test-utils'; import { afterAll, @@ -14,6 +21,7 @@ import { import { BurnerWalletConnector } from '../BurnerWalletConnector'; import { BURNER_WALLET_PRIVATE_KEY, TESTNET_URL } from '../constants'; import type { BurnerWalletConfig } from '../types'; +import { PRIVATE_KEY, SCRIPT_TX_REQUEST, SIGNED_TX } from './mock-transaction'; import { createMockedStorage } from './mockedStorage'; const mockConfirm = vi.fn(); @@ -245,6 +253,50 @@ describe('Burner Wallet Connector', () => { }); }); + describe('signTransaction()', () => { + test('should throw error when not connected', async () => { + const connector = await getBurnerWallet(); + const address = getRandomB256(); + + await expect(() => + connector.signTransaction(address, SCRIPT_TX_REQUEST), + ).rejects.toThrow('Wallet not connected'); + }); + + test('should throw error when address is not found for the connector', async () => { + const connector = await getBurnerWallet(); + await connector.connect(); + const address = '0xInvalidAddress'; + + await expect(() => + connector.signTransaction(address, SCRIPT_TX_REQUEST), + ).rejects.toThrow('Address not found for the connector'); + }); + + test('should return signed transaction', async () => { + const storage = createMockedStorage(); + const burnerWallet = Wallet.fromPrivateKey(PRIVATE_KEY, fuelProvider); + await storage.setItem(BURNER_WALLET_PRIVATE_KEY, burnerWallet.privateKey); + const connector = await getBurnerWallet({ fuelProvider, storage }); + mockConfirm.mockImplementationOnce(() => true); + await connector.connect(); + expect(mockConfirm).toHaveBeenCalled(); + + const signedTransaction = await connector.signTransaction( + burnerWallet.address.toString(), + SCRIPT_TX_REQUEST, + ); + + const chainId = burnerWallet.provider.getChainId(); + const verifiedAddress = Signer.recoverAddress( + SCRIPT_TX_REQUEST.getTransactionId(chainId), + signedTransaction, + ); + expect(signedTransaction).toEqual(SIGNED_TX); + expect(verifiedAddress).toEqual(burnerWallet.address); + }); + }); + describe('accounts()', () => { test('throws error when not connected', async () => { const connector = await getBurnerWallet(); diff --git a/packages/burner-wallet-connector/src/tests/mock-transaction.ts b/packages/burner-wallet-connector/src/tests/mock-transaction.ts new file mode 100644 index 00000000..5fcd5133 --- /dev/null +++ b/packages/burner-wallet-connector/src/tests/mock-transaction.ts @@ -0,0 +1,48 @@ +import { ScriptTransactionRequest } from 'fuels'; + +export const SCRIPT_TX_REQUEST = new ScriptTransactionRequest({ + gasLimit: 5_000, + script: '0x', + scriptData: Uint8Array.from([]), + tip: 5, + maxFee: 20_000, + maturity: 0, + witnessLimit: 5000, + inputs: [ + { + type: 0, + id: '0x000000000000000000000000000000000000000000000000000000000000000000', + assetId: + '0x0000000000000000000000000000000000000000000000000000000000000000', + amount: '0x989680', + owner: + '0xf1e92c42b90934aa6372e30bc568a326f6e66a1a0288595e6e3fbd392a4f3e6e', + txPointer: '0x00000000000000000000000000000000', + witnessIndex: 0, + predicate: '0x', + predicateData: '0x', + predicateGasUsed: '0x20', + }, + ], + outputs: [ + { + type: 0, + to: '0xc7862855b418ba8f58878db434b21053a61a2025209889cc115989e8040ff077', + assetId: + '0x0000000000000000000000000000000000000000000000000000000000000000', + amount: 1, + }, + ], + witnesses: ['0x'], +}); + +export const PRIVATE_KEY = + '0x5f70feeff1f229e4a95e1056e8b4d80d0b24b565674860cc213bdb07127ce1b1'; +export const PUBLIC_KEY = + '0x2f34bc0df4db0ec391792cedb05768832b49b1aa3a2dd8c30054d1af00f67d00b74b7acbbf3087c8e0b1a4c343db50aa471d21f278ff5ce09f07795d541fb47e'; +export const ADDRESS = + '0xf1e92c42b90934aa6372e30bc568a326f6e66a1a0288595e6e3fbd392a4f3e6e'; +export const HASHED_TX = + '0x48ee795d94ea9562a3dbb9979cb44bb3dfd341eb755c378b14a3cd6886189980'; +export const SIGNED_TX = + '0xbcc4d4988bf698ce45406e71112470ace2a6136bddf7dc1df87bfcc13d6a712ca82fa109cb697d02b14c3a6123fa0e06f4741aa0ee76f86cb26afac38ac493cb';