Skip to content

Commit 8e57e56

Browse files
committed
add txServiceUrl in safe config
1 parent 4970243 commit 8e57e56

File tree

6 files changed

+82
-47
lines changed

6 files changed

+82
-47
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@open-ibc/vibc-core-smart-contracts",
3-
"version": "4.0.9",
3+
"version": "4.0.10",
44
"main": "dist/index.js",
55
"bin": {
66
"verify-vibc-core-smart-contracts": "./dist/scripts/verify-contract-script.js",

src/evm/schemas/multisig.ts

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const uninitializedMultisigConfig = z
88
privateKey: z.string().min(1),
99
owners: z.array(z.string().min(1)),
1010
threshold: z.number(),
11+
txServiceUrl: z.string().optional()
1112
})
1213
.strict();
1314

@@ -18,6 +19,7 @@ export const initializedMultisigConfig = z
1819
chainId: z.number(),
1920
privateKey: z.string().min(1),
2021
safeAddress: z.string().min(1),
22+
txServiceUrl: z.string().optional(),
2123
})
2224
.strict();
2325

@@ -37,6 +39,7 @@ export const initializedMultisig = z.object({
3739
privateKey: z.string().min(1),
3840
safeAddress: z.string().min(1),
3941
wallet: wallet,
42+
txServiceUrl: z.string().optional(),
4043
});
4144

4245
export type UninitializedMultisigConfig = z.infer<

src/multisig/safe.ts

+75-37
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import SafeApiKit from "@safe-global/api-kit";
22
import Safe, { SafeFactory } from "@safe-global/protocol-kit";
33
import {
4+
MetaTransactionData,
45
OperationType,
5-
SafeTransactionDataPartial,
66
TransactionResult,
77
} from "@safe-global/safe-core-sdk-types";
8-
import { ethers } from "ethers";
8+
import { InitializedMultisig } from "../evm/schemas/multisig";
99

1010
/*
1111
* Init a safe owner from a given private key to a give RPC's network
@@ -37,36 +37,31 @@ export const newSafeFromOwner = async (
3737
* @param data Propose a transaction from a signer account
3838
*/
3939
export async function proposeTransaction(
40-
safeAddress: string,
40+
initializedMultisig: InitializedMultisig,
4141
toAddress: string,
4242
txData: string,
43-
proposerPrivateKey: string,
44-
chainId: bigint,
4543
rpcUrl: string,
4644
nonce: number,
4745
value = "0",
4846
operation = OperationType.Call
4947
) {
50-
const apiKit = new SafeApiKit({ chainId });
48+
console.log(
49+
`proposing transaction from \n \n @safe ${initializedMultisig.safeAddress} to ${toAddress} with value: ${value} and data: ${txData}, and nonce : ${nonce}`
50+
);
5151

5252
const txProposer = await Safe.init({
5353
provider: rpcUrl,
54-
signer: proposerPrivateKey,
55-
safeAddress: safeAddress,
54+
signer: initializedMultisig.wallet.privateKey,
55+
safeAddress: initializedMultisig.safeAddress,
5656
});
5757

58-
console.log(
59-
`proposing transaction from ${txProposer} @safe ${safeAddress} to ${toAddress} with value: ${value} and data: ${txData}, and nonce : ${nonce}`
60-
);
61-
62-
const txProposerAddress = new ethers.Wallet(proposerPrivateKey).address;
58+
const txProposerAddress = initializedMultisig.wallet.address;
6359

64-
const safeTransactionData: SafeTransactionDataPartial = {
60+
const safeTransactionData: MetaTransactionData = {
6561
to: toAddress,
6662
value,
6763
data: txData,
6864
operation: operation,
69-
nonce,
7065
};
7166

7267
const safeTransaction = await txProposer.createTransaction({
@@ -76,43 +71,86 @@ export async function proposeTransaction(
7671
const safeTxHash = await txProposer.getTransactionHash(safeTransaction);
7772

7873
const proposerSignature = await txProposer.signHash(safeTxHash);
79-
80-
// Propose transaction to the service
81-
await apiKit.proposeTransaction({
82-
safeAddress,
83-
safeTransactionData: safeTransaction.data,
84-
safeTxHash,
85-
senderAddress: txProposerAddress,
86-
senderSignature: proposerSignature.data,
87-
});
88-
89-
console.log(
90-
`Transaction has been proposed with hash: ${safeTxHash} from address ${txProposerAddress}`
91-
);
92-
return await apiKit.getTransaction(safeTxHash);
74+
if (initializedMultisig.txServiceUrl) {
75+
// For custom tx services, we have to submit our own http request since it seems like the safeApiKit.proposeTransaction method isn't compatible with some tx service urls
76+
77+
const url = `${initializedMultisig.txServiceUrl}/v1/chains/${initializedMultisig.chainId}/transactions/${initializedMultisig.safeAddress}/propose`;
78+
const body = JSON.stringify({
79+
...safeTransaction.data,
80+
nonce: nonce.toString(),
81+
signature: proposerSignature.data,
82+
sender: txProposerAddress,
83+
safeTxHash,
84+
});
85+
86+
console.log(`proposing transaction to tx service:${url} \n `);
87+
console.log(`with body${body}`);
88+
try {
89+
const res = await fetch(url, {
90+
method: "POST",
91+
headers: {
92+
"Content-Type": "application/json",
93+
},
94+
body,
95+
});
96+
97+
const json = await res.json();
98+
99+
if (!res.ok) {
100+
console.log(
101+
`received non 200 response from tx service ${res.status} ${json.message}`
102+
);
103+
}
104+
return json;
105+
} catch (e) {
106+
console.log(
107+
`error sending pending multisig tx to tx service ${initializedMultisig.txServiceUrl}`,
108+
e
109+
);
110+
111+
return;
112+
}
113+
} else {
114+
const apiKit = new SafeApiKit({
115+
chainId: BigInt(initializedMultisig.chainId),
116+
});
117+
// Propose transaction to the service
118+
await apiKit.proposeTransaction({
119+
safeAddress: initializedMultisig.safeAddress,
120+
safeTransactionData: safeTransaction.data,
121+
safeTxHash,
122+
senderAddress: txProposerAddress,
123+
senderSignature: proposerSignature.data,
124+
});
125+
console.log(
126+
`Transaction has been proposed with hash: ${safeTxHash} from address ${txProposerAddress}`
127+
);
128+
return await apiKit.getTransaction(safeTxHash);
129+
}
93130
}
94131

95132
/**
96133
* Execute a multisig tx from an account generated from proposeTransaction
97134
*/
98135
export const executeMultisigTx = async (
99-
safeAddress: string,
100-
executorPrivateKey: string,
101-
chainId: bigint,
136+
initializedMultisig: InitializedMultisig,
102137
rpcUrl: string,
103138
pendingTransactionIndex: number
104-
):Promise<TransactionResult> => {
139+
): Promise<TransactionResult> => {
105140
const apiKit = new SafeApiKit({
106-
chainId,
141+
chainId: BigInt(initializedMultisig.chainId),
142+
txServiceUrl: initializedMultisig.txServiceUrl,
107143
});
108144

109145
const executor = await Safe.init({
110146
provider: rpcUrl,
111-
signer: executorPrivateKey,
112-
safeAddress,
147+
signer: initializedMultisig.wallet.privateKey,
148+
safeAddress: initializedMultisig.safeAddress,
113149
});
114150

115-
const transactions = await apiKit.getPendingTransactions(safeAddress);
151+
const transactions = await apiKit.getPendingTransactions(
152+
initializedMultisig.safeAddress
153+
);
116154

117155
if (transactions.results.length <= pendingTransactionIndex) {
118156
throw new Error(

src/scripts/execute-multisig-tx.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,8 @@ async function main() {
2020
throw new Error("Can only execute transactions on a multisig wallet");
2121
}
2222

23-
const privateKey = accounts.getSinglePrivateKeyFromAccount(executor);
24-
2523
executeMultisigTx(
26-
multisigAccount.safeAddress,
27-
privateKey,
28-
BigInt(multisigAccount.chainId),
24+
multisigAccount,
2925
rpcUrl,
3026
txIndex
3127
);

src/tx.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,9 @@ export async function sendTx(
7676
);
7777

7878
proposeTransaction(
79-
account.safeAddress,
79+
account,
8080
deployedContractAddress,
8181
callData,
82-
account.wallet.privateKey,
83-
BigInt(chain.chainId),
8482
chain.rpc,
8583
updatedNonces[account.safeAddress]
8684
);

src/utils/io.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,6 @@ export const saveMultisigAddressToAccountsSpec = async (
516516
accountsSpecPath: string,
517517
chainId: number,
518518
ownerName: string // Used to find which owner to write to,
519-
520519
) => {
521520
// TODO: Currently this yaml lib doesn't include comments - we need to figure out a way to preserve comments / whitespaces, etc
522521
const yamlFile = readYamlFile(accountsSpecPath);
@@ -532,6 +531,7 @@ export const saveMultisigAddressToAccountsSpec = async (
532531
chainId,
533532
safeAddress: newSafeAddress,
534533
privateKey: account.privateKey,
534+
txServiceUrl: account.txServiceUrl
535535
};
536536
});
537537

0 commit comments

Comments
 (0)