diff --git a/apps/web/src/components/beacon/useHandleBeaconMessage.test.tsx b/apps/web/src/components/beacon/useHandleBeaconMessage.test.tsx index 0172f51864..5f56ac807c 100644 --- a/apps/web/src/components/beacon/useHandleBeaconMessage.test.tsx +++ b/apps/web/src/components/beacon/useHandleBeaconMessage.test.tsx @@ -2,29 +2,18 @@ import { BeaconMessageType, type BeaconRequestOutputMessage, NetworkType, - type PartialTezosOperation, type PermissionRequestOutput, PermissionScope, type SignPayloadRequestOutput, SigningType, TezosOperationType, } from "@airgap/beacon-wallet"; -import { - estimate, - makeAccountOperations, - mockImplicitAccount, - mockTezOperation, -} from "@umami/core"; +import { estimate, makeAccountOperations, mockImplicitAccount } from "@umami/core"; import { type UmamiStore, WalletClient, addTestAccount, makeStore, mockToast } from "@umami/state"; import { executeParams } from "@umami/test-utils"; -import { mockContractAddress, mockImplicitAddress } from "@umami/tezos"; -import { without } from "lodash"; +import { mockImplicitAddress } from "@umami/tezos"; -import { - partialOperationToOperation, - toAccountOperations, - useHandleBeaconMessage, -} from "./useHandleBeaconMessage"; +import { useHandleBeaconMessage } from "./useHandleBeaconMessage"; import { BatchSignPage } from "../../components/SendFlow/Beacon/BatchSignPage"; import { BeaconSignPage } from "../../components/SendFlow/Beacon/BeaconSignPage"; import { act, dynamicModalContextMock, renderHook, screen, waitFor } from "../../testUtils"; @@ -518,170 +507,3 @@ describe("", () => { }); }); }); - -describe("toAccountOperations", () => { - it("throws if the list is empty", () => { - expect(() => toAccountOperations([], account)).toThrow("Empty operation details!"); - }); - - it("converts a list of partial operations to ImplicitOperations", () => { - const operationDetails: PartialTezosOperation[] = [ - { - kind: TezosOperationType.TRANSACTION, - amount: "1", - destination: mockImplicitAddress(2).pkh, - }, - { - kind: TezosOperationType.TRANSACTION, - amount: "2", - destination: mockImplicitAddress(2).pkh, - }, - ]; - - const operations = toAccountOperations(operationDetails, account); - - expect(operations).toEqual( - makeAccountOperations(account, account, [ - { type: "tez", amount: "1", recipient: mockImplicitAddress(2) }, - { type: "tez", amount: "2", recipient: mockImplicitAddress(2) }, - ]) - ); - }); -}); - -describe("partialOperationToOperation", () => { - describe.each( - without( - Object.values(TezosOperationType), - TezosOperationType.TRANSACTION, - TezosOperationType.DELEGATION, - TezosOperationType.ORIGINATION - ) - )("for %s", kind => { - it("throws an error", () => { - const operation: PartialTezosOperation = { kind } as PartialTezosOperation; - - expect(() => partialOperationToOperation(operation, account)).toThrow( - `Unsupported operation kind: ${kind}` - ); - }); - }); - - test("tez transaction", () => { - const operation: PartialTezosOperation = { - kind: TezosOperationType.TRANSACTION, - amount: "1", - destination: mockImplicitAddress(2).pkh, - }; - - const result = partialOperationToOperation(operation, account); - - expect(result).toEqual(mockTezOperation(1)); - }); - - test("stake", () => { - const operation: PartialTezosOperation = { - kind: TezosOperationType.TRANSACTION, - amount: "1", - destination: mockImplicitAddress(2).pkh, - parameters: { - entrypoint: "stake", - value: [{ prim: "UNIT" }], - }, - }; - - const result = partialOperationToOperation(operation, account); - - expect(result).toEqual({ - type: "stake", - amount: "1", - sender: mockImplicitAddress(2), - }); - }); - - test("unstake", () => { - const operation: PartialTezosOperation = { - kind: TezosOperationType.TRANSACTION, - amount: "12", - destination: mockImplicitAddress(2).pkh, - parameters: { - entrypoint: "unstake", - value: [{ prim: "UNIT" }], - }, - }; - - const result = partialOperationToOperation(operation, account); - - expect(result).toEqual({ - type: "unstake", - amount: "12", - sender: mockImplicitAddress(2), - }); - }); - - test("finalize unstake", () => { - const operation: PartialTezosOperation = { - kind: TezosOperationType.TRANSACTION, - destination: mockImplicitAddress(2).pkh, - amount: "0", - parameters: { - entrypoint: "finalize_unstake", - value: [{ prim: "UNIT" }], - }, - }; - - const result = partialOperationToOperation(operation, account); - - expect(result).toEqual({ - type: "finalize_unstake", - sender: mockImplicitAddress(2), - }); - }); - - test("contract call", () => { - const operation: PartialTezosOperation = { - kind: TezosOperationType.TRANSACTION, - amount: "1", - destination: mockContractAddress(2).pkh, - parameters: { - entrypoint: "mockEntrypoint", - value: [{ prim: "UNIT" }], - }, - }; - - const result = partialOperationToOperation(operation, account); - - expect(result).toEqual({ - type: "contract_call", - amount: "1", - contract: mockContractAddress(2), - entrypoint: "mockEntrypoint", - args: [{ prim: "UNIT" }], - }); - }); - - test("delegate", () => { - const operation: PartialTezosOperation = { - kind: TezosOperationType.DELEGATION, - delegate: mockImplicitAddress(2).pkh, - }; - - const result = partialOperationToOperation(operation, account); - - expect(result).toEqual({ - type: "delegation", - sender: account.address, - recipient: mockImplicitAddress(2), - }); - }); - - test("undelegate", () => { - const operation: PartialTezosOperation = { - kind: TezosOperationType.DELEGATION, - }; - - const result = partialOperationToOperation(operation, account); - - expect(result).toEqual({ type: "undelegation", sender: account.address }); - }); -}); diff --git a/apps/web/src/components/beacon/useHandleBeaconMessage.tsx b/apps/web/src/components/beacon/useHandleBeaconMessage.tsx index f56bc0bf81..834f9fe441 100644 --- a/apps/web/src/components/beacon/useHandleBeaconMessage.tsx +++ b/apps/web/src/components/beacon/useHandleBeaconMessage.tsx @@ -3,17 +3,9 @@ import { BeaconMessageType, type Network as BeaconNetwork, type BeaconRequestOutputMessage, - type PartialTezosOperation, - TezosOperationType, } from "@airgap/beacon-wallet"; import { useDynamicModalContext } from "@umami/components"; -import { - type ContractOrigination, - type ImplicitAccount, - type ImplicitOperations, - type Operation, - estimate, -} from "@umami/core"; +import { type ImplicitAccount, estimate, toAccountOperations } from "@umami/core"; import { WalletClient, useAsyncActionHandler, @@ -21,7 +13,7 @@ import { useGetOwnedAccountSafe, useRemovePeerBySenderId, } from "@umami/state"; -import { type Network, isValidImplicitPkh, parseImplicitPkh, parsePkh } from "@umami/tezos"; +import { type Network } from "@umami/tezos"; import { PermissionRequestModal } from "./PermissionRequestModal"; import { SignPayloadRequestModal } from "./SignPayloadRequestModal"; @@ -151,106 +143,3 @@ export const useHandleBeaconMessage = () => { ); }; }; - -/** - * takes a list of {@link PartialTezosOperation} which come from Beacon - * and converts them to {@link ImplicitOperations} - * - * @param operationDetails - the list of operations to convert - * @param signer - the {@link Account} that's going to sign the operation - * @returns - */ -export const toAccountOperations = ( - operationDetails: PartialTezosOperation[], - signer: ImplicitAccount -): ImplicitOperations => { - if (operationDetails.length === 0) { - throw new Error("Empty operation details!"); - } - - const operations = operationDetails.map(operation => - partialOperationToOperation(operation, signer) - ); - - return { - type: "implicit", - sender: signer, - operations, - signer, - }; -}; - -/** - * Converts a {@link PartialTezosOperation} which comes from Beacon to a {@link Operation} - * - * Note: it doesn't supported all of the possible operation types, but only a subset of them. - * - * @param partialOperation - the operation to convert - * @param signer - the {@link Account} that's going to sign the operation - * @returns a parsed {@link Operation} - */ -export const partialOperationToOperation = ( - partialOperation: PartialTezosOperation, - signer: ImplicitAccount -): Operation => { - switch (partialOperation.kind) { - case TezosOperationType.TRANSACTION: { - const { destination, amount, parameters } = partialOperation; - if (parameters) { - // if the destination is an implicit account then it's a pseudo operation - if (isValidImplicitPkh(destination)) { - switch (parameters.entrypoint) { - case "stake": - return { type: "stake", amount, sender: parseImplicitPkh(destination) }; - case "unstake": - return { type: "unstake", amount, sender: parseImplicitPkh(destination) }; - case "finalize_unstake": - return { type: "finalize_unstake", sender: parseImplicitPkh(destination) }; - } - } - - return { - type: "contract_call", - amount, - contract: parsePkh(destination), - entrypoint: parameters.entrypoint, - args: parameters.value, - }; - } - - return { - type: "tez", - amount, - recipient: parseImplicitPkh(partialOperation.destination), - }; - } - case TezosOperationType.DELEGATION: { - const { delegate } = partialOperation; - - if (delegate) { - return { - type: "delegation", - sender: signer.address, - recipient: parseImplicitPkh(delegate), - }; - } - return { type: "undelegation", sender: signer.address }; - } - case TezosOperationType.ORIGINATION: { - const { script } = partialOperation; - const { code, storage } = script as unknown as { - code: ContractOrigination["code"]; - storage: ContractOrigination["storage"]; - }; - - return { - type: "contract_origination", - sender: signer.address, - code, - storage, - }; - } - default: - throw new Error(`Unsupported operation kind: ${partialOperation.kind}`); - } -};