Skip to content

Commit

Permalink
Merge pull request #781 from hats-finance/fix/safe-sdk-migration
Browse files Browse the repository at this point in the history
chore: safe sdk migration
  • Loading branch information
shayzluf authored Dec 1, 2024
2 parents 5da7ff6 + 03c316e commit 8760bb0
Show file tree
Hide file tree
Showing 12 changed files with 941 additions and 3,068 deletions.
2,578 changes: 639 additions & 1,939 deletions package-lock.json

Large diffs are not rendered by default.

81 changes: 0 additions & 81 deletions packages/shared/package-lock.json

This file was deleted.

6 changes: 3 additions & 3 deletions packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
"private": false,
"devDependencies": {
"@types/uuid": "^9.0.0",
"typescript": "^4.9.4"
"typescript": "^5.7.2"
},
"dependencies": {
"@safe-global/protocol-kit": "^1.0.1",
"@safe-global/safe-core-sdk-types": "^2.0.0",
"@safe-global/protocol-kit": "^5.0.4",
"@safe-global/types-kit": "^1.0.0",
"@wagmi/chains": "1.8.0-cjs",
"ethers": "^5.7.2",
"uuid": "^9.0.0"
Expand Down
41 changes: 23 additions & 18 deletions packages/shared/src/utils/payouts.utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Safe, { EthersAdapter } from "@safe-global/protocol-kit";
import { SafeTransaction } from "@safe-global/safe-core-sdk-types";
import Safe from "@safe-global/protocol-kit";
import { SafeTransaction } from "@safe-global/types-kit";
import axios, { AxiosResponse } from "axios";
import { BigNumber, ethers } from "ethers";
import { BigNumber, Signer, ethers } from "ethers";
import { formatUnits, getAddress, parseUnits } from "ethers/lib/utils.js";
import { HATPaymentSplitterFactory_abi, HATSVaultV1_abi, HATSVaultV2_abi, HATSVaultV3ClaimsManager_abi } from "../abis";
import {
Expand Down Expand Up @@ -55,14 +55,18 @@ export const createNewSplitPayoutBeneficiary = (): ISplitPayoutBeneficiary => {
};

export const getExecutePayoutSafeTransaction = async (
provider: ethers.providers.Provider,
signer: Signer,
committee: string,
payout: IPayoutResponse
): Promise<{ tx: SafeTransaction; txHash: string }> => {
const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: provider });
const safeSdk = await Safe.create({ ethAdapter: ethAdapter, safeAddress: committee });

const vaultInfo = payout.vaultInfo;

const protocolKit = await Safe.init({
provider: (signer.provider as any)?.provider as never,
safeAddress: committee,
signer: (await signer.getAddress()) as never,
});

const percentageToPay = Math.round(Number(payout.payoutData.percentageToPay) * 100);

if (payout.payoutData.type === "single") {
Expand Down Expand Up @@ -100,15 +104,16 @@ export const getExecutePayoutSafeTransaction = async (
]);
}

const safeTransaction = await safeSdk.createTransaction({
safeTransactionData: {
to: contractAddress,
data: encodedExecPayoutData,
value: "0",
safeTxGas: "0",
},
const safeTransaction = await protocolKit.createTransaction({
transactions: [
{
to: contractAddress,
data: encodedExecPayoutData,
value: "0",
},
],
});
const safeTransactionHash = await safeSdk.getTransactionHash(safeTransaction);
const safeTransactionHash = await protocolKit.getTransactionHash(safeTransaction);

return { tx: safeTransaction, txHash: safeTransactionHash };
} else {
Expand Down Expand Up @@ -232,8 +237,8 @@ export const getExecutePayoutSafeTransaction = async (
payout.payoutDescriptionHash,
]);

const safeTransaction = await safeSdk.createTransaction({
safeTransactionData: [
const safeTransaction = await protocolKit.createTransaction({
transactions: [
{
to: paymentSplitterFactoryAddress,
data: encodedPaymentSplitterCreation,
Expand All @@ -246,7 +251,7 @@ export const getExecutePayoutSafeTransaction = async (
},
],
});
const safeTransactionHash = await safeSdk.getTransactionHash(safeTransaction);
const safeTransactionHash = await protocolKit.getTransactionHash(safeTransaction);

return { tx: safeTransaction, txHash: safeTransactionHash };
}
Expand Down
10 changes: 5 additions & 5 deletions packages/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"stream-http": "^3.2.0",
"styled-components": "^5.3.6",
"swiper": "^8.3.0",
"typescript": "^4.9.4",
"typescript": "^5.7.2",
"url": "^0.11.0",
"util": "^0.12.4",
"uuid": "^9.0.0",
Expand Down Expand Up @@ -104,9 +104,9 @@
]
},
"dependencies": {
"@safe-global/api-kit": "^1.1.0",
"@safe-global/protocol-kit": "^1.0.1",
"@safe-global/safe-core-sdk-types": "^2.0.0",
"@safe-global/api-kit": "^2.5.4",
"@safe-global/protocol-kit": "^5.0.4",
"@safe-global/types-kit": "^1.0.0",
"@tanstack/react-query": "^4.28.0",
"@walletconnect/modal": "^2.6.2",
"csvtojson": "^2.0.10",
Expand All @@ -124,4 +124,4 @@
"siwe": "^1.1.6",
"uuid-by-string": "^4.0.0"
}
}
}
21 changes: 11 additions & 10 deletions packages/web/src/contracts/write/ExecutePayout.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { IPayoutResponse, getExecutePayoutSafeTransaction } from "@hats.finance/shared";
import Safe, { EthSafeSignature, EthersAdapter } from "@safe-global/protocol-kit";
import { TransactionResult } from "@safe-global/safe-core-sdk-types";
import { Signer, ethers } from "ethers";
import Safe, { EthSafeSignature } from "@safe-global/protocol-kit";
import { TransactionResult } from "@safe-global/types-kit";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { IVault } from "types";
import { switchNetworkAndValidate } from "utils/switchNetwork.utils";
import { useNetwork, useProvider, useSigner } from "wagmi";
import { useNetwork, useSigner } from "wagmi";

export class ExecutePayoutContract {
/**
Expand All @@ -20,7 +19,6 @@ export class ExecutePayoutContract {
static hook = (vault?: IVault, payout?: IPayoutResponse) => {
const { t } = useTranslation();
const { chain } = useNetwork();
const provider = useProvider();
const { data: signer } = useSigner();

const [data, setData] = useState<TransactionResult | undefined>();
Expand All @@ -36,20 +34,23 @@ export class ExecutePayoutContract {
isError: !!error,
send: async () => {
try {
if (!vault || !payout || !contractAddress) return;
if (!vault || !payout || !contractAddress || !signer) return;
setError(undefined);
setIsLoading(true);

await switchNetworkAndValidate(chain!.id, vault.chainId as number);

console.log("Getting Safe SDK");
const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: signer as Signer });
const safeSdk = await Safe.create({ ethAdapter, safeAddress: vault.committee });
const protocolKit = await Safe.init({
provider: (signer.provider as any)?.provider as never,
safeAddress: vault.committee,
signer: (await signer.getAddress()) as never,
});
console.log("Safe SDK done");

console.log("Getting safe TX");
const { tx: safeTransaction, txHash: safeTransactionHash } = await getExecutePayoutSafeTransaction(
provider,
signer,
vault.committee,
payout
);
Expand All @@ -66,7 +67,7 @@ export class ExecutePayoutContract {
}

console.log("Executing safe transaction");
const txResult = await safeSdk.executeTransaction(safeTransaction);
const txResult = await protocolKit.executeTransaction(safeTransaction);
console.log("Safe transaction executed", txResult);
setData(txResult);
setIsLoading(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import { IPayoutResponse, IVault, getExecutePayoutSafeTransaction, getGnosisSafeTxServiceBaseUrl } from "@hats.finance/shared";
import SafeApiKit from "@safe-global/api-kit";
import Safe, { EthersAdapter } from "@safe-global/protocol-kit";
import { Signer, ethers, utils } from "ethers";
import Safe from "@safe-global/protocol-kit";
import { utils } from "ethers";
import { useState } from "react";
import { useAccount, useProvider, useSigner } from "wagmi";
import { useAccount, useSigner } from "wagmi";

export const useCreatePayoutProposal = (vault?: IVault, payout?: IPayoutResponse) => {
const { address: account } = useAccount();
const provider = useProvider();
const { data: signer } = useSigner();

const [isLoading, setIsLoading] = useState(false);

const create = async () => {
try {
if (!vault || !payout || !account) return false;
if (!vault || !payout || !account || !signer) return false;
setIsLoading(true);

let multisigAddress: string | undefined;
Expand All @@ -30,15 +29,19 @@ export const useCreatePayoutProposal = (vault?: IVault, payout?: IPayoutResponse
return false;
}

const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: signer as Signer });
const protocolKit = await Safe.init({
provider: (signer.provider as any)?.provider as never,
safeAddress: multisigAddress,
signer: (await signer.getAddress()) as never,
});

const txServiceUrl = getGnosisSafeTxServiceBaseUrl(vault.chainId);
const safeService = new SafeApiKit({ txServiceUrl, ethAdapter });
const safeSdk = await Safe.create({ ethAdapter, safeAddress: multisigAddress });
const safeService = new SafeApiKit({ txServiceUrl: `${txServiceUrl}/api`, chainId: BigInt(vault.chainId) });

const { tx: safeTransaction } = await getExecutePayoutSafeTransaction(provider, multisigAddress, payout);
const { tx: safeTransaction } = await getExecutePayoutSafeTransaction(signer, multisigAddress, payout);

const safeTxHash = await safeSdk.getTransactionHash(safeTransaction);
const senderSignature = await safeSdk.signTypedData(safeTransaction);
const safeTxHash = await protocolKit.getTransactionHash(safeTransaction);
const senderSignature = await protocolKit.signTypedData(safeTransaction);
await safeService.proposeTransaction({
safeAddress: multisigAddress,
safeTransactionData: safeTransaction.data,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
import { IPayoutResponse, IVault, getExecutePayoutSafeTransaction } from "@hats.finance/shared";
import Safe, { EthersAdapter } from "@safe-global/protocol-kit";
import { Signer, ethers } from "ethers";
import Safe from "@safe-global/protocol-kit";
import { useState } from "react";
import { switchNetworkAndValidate } from "utils/switchNetwork.utils";
import { useNetwork, useProvider, useSignTypedData, useSigner } from "wagmi";
import { useNetwork, useSignTypedData, useSigner } from "wagmi";

export const useSignPayout = (vault?: IVault, payout?: IPayoutResponse) => {
const { chain } = useNetwork();
const provider = useProvider();
const { data: signer } = useSigner();
const signPayout = useSignTypedData();

const [isLoading, setIsLoading] = useState(false);

const signTypedData = async () => {
if (!vault || !payout) return;
if (!vault || !payout || !signer) return;
setIsLoading(true);

try {
await switchNetworkAndValidate(chain!.id, vault.chainId as number);

const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: signer as Signer });
const safeSdk = await Safe.create({ ethAdapter, safeAddress: vault.committee });
const protocolKit = await Safe.init({
provider: (signer.provider as any)?.provider as never,
safeAddress: vault.committee,
signer: (await signer.getAddress()) as never,
});

const { tx: safeTransaction } = await getExecutePayoutSafeTransaction(provider, vault.committee, payout);
const { tx: safeTransaction } = await getExecutePayoutSafeTransaction(signer, vault.committee, payout);

const signature = await safeSdk.signTypedData(safeTransaction);
const signature = await protocolKit.signTypedData(safeTransaction);

return signature.data;
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export const VaultAsset = ({ vault }: VaultAssetProps) => {
const { isShowing: isShowingDepositModal, show: showDepositModal, hide: hideDepositModal } = useModal();

const vaultApy = useVaultApy(vault);
console.log(vaultApy);

const isAudit = vault.description && vault.description["project-metadata"].type === "audit";
const depositsDisabled = !vault.committeeCheckedIn || vault.depositPause;
Expand Down
Loading

0 comments on commit 8760bb0

Please sign in to comment.