@safe-global/protocol-kit 2.0.0 → 3.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/src/Safe.d.ts +57 -7
- package/dist/src/Safe.js +222 -38
- package/dist/src/Safe.js.map +1 -1
- package/dist/src/adapters/ethers/EthersAdapter.d.ts +2 -2
- package/dist/src/adapters/ethers/EthersAdapter.js +5 -3
- package/dist/src/adapters/ethers/EthersAdapter.js.map +1 -1
- package/dist/src/adapters/ethers/contracts/CreateCall/CreateCallEthersContract.js.map +1 -1
- package/dist/src/adapters/ethers/contracts/Safe/SafeContractEthers.js.map +1 -1
- package/dist/src/adapters/ethers/contracts/Safe/v1.0.0/SafeContract_V1_0_0_Ethers.js.map +1 -1
- package/dist/src/adapters/ethers/contracts/Safe/v1.1.1/SafeContract_V1_1_1_Ethers.js.map +1 -1
- package/dist/src/adapters/ethers/contracts/Safe/v1.2.0/SafeContract_V1_2_0_Ethers.js.map +1 -1
- package/dist/src/adapters/ethers/contracts/Safe/v1.3.0/SafeContract_V1_3_0_Ethers.js.map +1 -1
- package/dist/src/adapters/ethers/contracts/Safe/v1.4.1/SafeContract_V1_4_1_Ethers.js.map +1 -1
- package/dist/src/adapters/ethers/contracts/SafeProxyFactory/SafeProxyFactoryEthersContract.js.map +1 -1
- package/dist/src/adapters/ethers/contracts/SignMessageLib/SignMessageLibEthersContract.js.map +1 -1
- package/dist/src/adapters/ethers/contracts/contractInstancesEthers.js.map +1 -1
- package/dist/src/adapters/web3/Web3Adapter.d.ts +2 -2
- package/dist/src/adapters/web3/Web3Adapter.js +6 -5
- package/dist/src/adapters/web3/Web3Adapter.js.map +1 -1
- package/dist/src/adapters/web3/contracts/CreateCall/CreateCallWeb3Contract.js.map +1 -1
- package/dist/src/adapters/web3/contracts/Safe/SafeContractWeb3.js.map +1 -1
- package/dist/src/adapters/web3/contracts/Safe/v1.0.0/SafeContract_V1_0_0_Web3.js.map +1 -1
- package/dist/src/adapters/web3/contracts/Safe/v1.1.1/SafeContract_V1_1_1_Web3.js.map +1 -1
- package/dist/src/adapters/web3/contracts/Safe/v1.2.0/SafeContract_V1_2_0_Web3.js.map +1 -1
- package/dist/src/adapters/web3/contracts/Safe/v1.3.0/SafeContract_V1_3_0_Web3.js.map +1 -1
- package/dist/src/adapters/web3/contracts/Safe/v1.4.1/SafeContract_V1_4_1_Web3.js.map +1 -1
- package/dist/src/adapters/web3/contracts/SafeProxyFactory/SafeProxyFactoryWeb3Contract.js.map +1 -1
- package/dist/src/adapters/web3/contracts/SignMessageLib/SignMessageLibWeb3Contract.js.map +1 -1
- package/dist/src/adapters/web3/contracts/contractInstancesWeb3.js.map +1 -1
- package/dist/src/contracts/safeDeploymentContracts.d.ts +2 -3
- package/dist/src/contracts/safeDeploymentContracts.js.map +1 -1
- package/dist/src/contracts/utils.d.ts +2 -1
- package/dist/src/contracts/utils.js +12 -9
- package/dist/src/contracts/utils.js.map +1 -1
- package/dist/src/index.d.ts +5 -3
- package/dist/src/index.js +17 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/managers/contractManager.js.map +1 -1
- package/dist/src/managers/fallbackHandlerManager.js.map +1 -1
- package/dist/src/managers/guardManager.js.map +1 -1
- package/dist/src/managers/moduleManager.js.map +1 -1
- package/dist/src/managers/ownerManager.js.map +1 -1
- package/dist/src/safeFactory/index.js +1 -0
- package/dist/src/safeFactory/index.js.map +1 -1
- package/dist/src/types/index.d.ts +8 -0
- package/dist/src/types/index.js +9 -0
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/utils/eip-3770/config.js +21 -1
- package/dist/src/utils/eip-3770/config.js.map +1 -1
- package/dist/src/utils/eip-3770/index.js.map +1 -1
- package/dist/src/utils/eip-712/index.d.ts +6 -9
- package/dist/src/utils/eip-712/index.js +57 -18
- package/dist/src/utils/eip-712/index.js.map +1 -1
- package/dist/src/utils/erc-20/index.js.map +1 -1
- package/dist/src/utils/messages/SafeMessage.d.ts +10 -0
- package/dist/src/utils/messages/SafeMessage.js +20 -0
- package/dist/src/utils/messages/SafeMessage.js.map +1 -0
- package/dist/src/utils/safeVersions.js +1 -1
- package/dist/src/utils/safeVersions.js.map +1 -1
- package/dist/src/utils/signatures/SafeSignature.d.ts +3 -2
- package/dist/src/utils/signatures/SafeSignature.js +10 -2
- package/dist/src/utils/signatures/SafeSignature.js.map +1 -1
- package/dist/src/utils/signatures/utils.d.ts +11 -4
- package/dist/src/utils/signatures/utils.js +75 -7
- package/dist/src/utils/signatures/utils.js.map +1 -1
- package/dist/src/utils/transactions/SafeTransaction.d.ts +1 -0
- package/dist/src/utils/transactions/SafeTransaction.js +5 -10
- package/dist/src/utils/transactions/SafeTransaction.js.map +1 -1
- package/dist/src/utils/transactions/gas.js.map +1 -1
- package/dist/src/utils/transactions/utils.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +11 -13
package/README.md
CHANGED
|
@@ -627,7 +627,7 @@ const safeTransaction = await safeSdk.createTransaction({ transactions })
|
|
|
627
627
|
const txHash = await safeSdk.getTransactionHash(safeTransaction)
|
|
628
628
|
```
|
|
629
629
|
|
|
630
|
-
###
|
|
630
|
+
### signHash
|
|
631
631
|
|
|
632
632
|
Signs a hash using the current owner account.
|
|
633
633
|
|
|
@@ -639,7 +639,7 @@ const transactions: MetaTransactionData[] = [
|
|
|
639
639
|
]
|
|
640
640
|
const safeTransaction = await safeSdk.createTransaction({ transactions })
|
|
641
641
|
const txHash = await safeSdk.getTransactionHash(safeTransaction)
|
|
642
|
-
const signature = await safeSdk.
|
|
642
|
+
const signature = await safeSdk.signHash(txHash)
|
|
643
643
|
```
|
|
644
644
|
|
|
645
645
|
### signTypedData
|
|
@@ -673,11 +673,14 @@ const signedSafeTransaction = await safeSdk.signTransaction(safeTransaction)
|
|
|
673
673
|
Optionally, an additional parameter can be passed to specify a different way of signing:
|
|
674
674
|
|
|
675
675
|
```js
|
|
676
|
-
const signedSafeTransaction = await safeSdk.signTransaction(
|
|
676
|
+
const signedSafeTransaction = await safeSdk.signTransaction(
|
|
677
|
+
safeTransaction,
|
|
678
|
+
SigningMethod.ETH_SIGN_TYPED_DATA
|
|
679
|
+
)
|
|
677
680
|
```
|
|
678
681
|
|
|
679
682
|
```js
|
|
680
|
-
const signedSafeTransaction = await safeSdk.signTransaction(safeTransaction,
|
|
683
|
+
const signedSafeTransaction = await safeSdk.signTransaction(safeTransaction, SigningMethod.ETH_SIGN) // default option.
|
|
681
684
|
```
|
|
682
685
|
|
|
683
686
|
### approveTransactionHash
|
package/dist/src/Safe.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { EthAdapter, SafeMultisigTransactionResponse, SafeSignature, SafeTransaction, SafeVersion, TransactionOptions, TransactionResult, MetaTransactionData, Transaction } from '@safe-global/safe-core-sdk-types';
|
|
1
|
+
import { EthAdapter, SafeMultisigTransactionResponse, SafeSignature, SafeTransaction, SafeVersion, TransactionOptions, TransactionResult, MetaTransactionData, Transaction, EIP712TypedData } from '@safe-global/safe-core-sdk-types';
|
|
2
2
|
import ContractManager from './managers/contractManager';
|
|
3
|
-
import { AddOwnerTxParams, ConnectSafeConfig, CreateTransactionProps, RemoveOwnerTxParams, SafeConfig, SwapOwnerTxParams } from './types';
|
|
3
|
+
import { AddOwnerTxParams, ConnectSafeConfig, CreateTransactionProps, RemoveOwnerTxParams, SafeConfig, SigningMethodType, SwapOwnerTxParams } from './types';
|
|
4
4
|
import { SafeTransactionOptionalProps } from './utils/transactions/types';
|
|
5
|
+
import SafeMessage from './utils/messages/SafeMessage';
|
|
5
6
|
declare class Safe {
|
|
6
7
|
#private;
|
|
7
8
|
/**
|
|
@@ -163,7 +164,7 @@ declare class Safe {
|
|
|
163
164
|
* Returns the transaction hash of a Safe transaction.
|
|
164
165
|
*
|
|
165
166
|
* @param safeTransaction - The Safe transaction
|
|
166
|
-
* @returns The
|
|
167
|
+
* @returns The hash of the Safe transaction
|
|
167
168
|
*/
|
|
168
169
|
getTransactionHash(safeTransaction: SafeTransaction): Promise<string>;
|
|
169
170
|
/**
|
|
@@ -172,24 +173,47 @@ declare class Safe {
|
|
|
172
173
|
* @param hash - The hash to sign
|
|
173
174
|
* @returns The Safe signature
|
|
174
175
|
*/
|
|
175
|
-
|
|
176
|
+
signHash(hash: string): Promise<SafeSignature>;
|
|
177
|
+
/**
|
|
178
|
+
* Returns a Safe message ready to be signed by the owners.
|
|
179
|
+
*
|
|
180
|
+
* @param message - The message
|
|
181
|
+
* @returns The Safe message
|
|
182
|
+
*/
|
|
183
|
+
createMessage(message: string | EIP712TypedData): SafeMessage;
|
|
184
|
+
/**
|
|
185
|
+
* Returns the Safe message with a new signature
|
|
186
|
+
*
|
|
187
|
+
* @param message The message to be signed
|
|
188
|
+
* @param signingMethod The signature type
|
|
189
|
+
* @param preimageSafeAddress If the preimage is required, the address of the Safe that will be used to calculate the preimage.
|
|
190
|
+
* This field is mandatory for 1.4.1 contract versions Because the safe uses the old EIP-1271 interface which uses `bytes` instead of `bytes32` for the message
|
|
191
|
+
* we need to use the pre-image of the message to calculate the message hash
|
|
192
|
+
* https://github.com/safe-global/safe-contracts/blob/192c7dc67290940fcbc75165522bb86a37187069/test/core/Safe.Signatures.spec.ts#L229-L233
|
|
193
|
+
* @returns The signed Safe message
|
|
194
|
+
*/
|
|
195
|
+
signMessage(message: SafeMessage, signingMethod?: SigningMethodType, preimageSafeAddress?: string): Promise<SafeMessage>;
|
|
176
196
|
/**
|
|
177
197
|
* Signs a transaction according to the EIP-712 using the current signer account.
|
|
178
198
|
*
|
|
179
|
-
* @param
|
|
199
|
+
* @param eip712Data - The Safe Transaction or message hash to be signed
|
|
180
200
|
* @param methodVersion - EIP-712 version. Optional
|
|
181
201
|
* @returns The Safe signature
|
|
182
202
|
*/
|
|
183
|
-
signTypedData(
|
|
203
|
+
signTypedData(eip712Data: SafeTransaction | SafeMessage, methodVersion?: 'v3' | 'v4'): Promise<SafeSignature>;
|
|
184
204
|
/**
|
|
185
205
|
* Adds the signature of the current signer to the Safe transaction object.
|
|
186
206
|
*
|
|
187
207
|
* @param safeTransaction - The Safe transaction to be signed
|
|
188
208
|
* @param signingMethod - Method followed to sign a transaction. Optional. Default value is "eth_sign"
|
|
209
|
+
* @param preimageSafeAddress - If the preimage is required, the address of the Safe that will be used to calculate the preimage
|
|
210
|
+
* This field is mandatory for 1.3.0 and 1.4.1 contract versions Because the safe uses the old EIP-1271 interface which uses `bytes` instead of `bytes32` for the message
|
|
211
|
+
* we need to use the pre-image of the message to calculate the message hash
|
|
212
|
+
* https://github.com/safe-global/safe-contracts/blob/192c7dc67290940fcbc75165522bb86a37187069/test/core/Safe.Signatures.spec.ts#L229-L233
|
|
189
213
|
* @returns The signed Safe transaction
|
|
190
214
|
* @throws "Transactions can only be signed by Safe owners"
|
|
191
215
|
*/
|
|
192
|
-
signTransaction(safeTransaction: SafeTransaction | SafeMultisigTransactionResponse, signingMethod?:
|
|
216
|
+
signTransaction(safeTransaction: SafeTransaction | SafeMultisigTransactionResponse, signingMethod?: SigningMethodType, preimageSafeAddress?: string): Promise<SafeTransaction>;
|
|
193
217
|
/**
|
|
194
218
|
* Approves on-chain a hash using the current signer account.
|
|
195
219
|
*
|
|
@@ -389,5 +413,31 @@ declare class Safe {
|
|
|
389
413
|
*
|
|
390
414
|
*/
|
|
391
415
|
createTransactionBatch(transactions: MetaTransactionData[], transactionOptions?: TransactionOptions): Promise<Transaction>;
|
|
416
|
+
/**
|
|
417
|
+
* Get the fallback handler contract
|
|
418
|
+
*
|
|
419
|
+
* @returns The fallback Handler contract
|
|
420
|
+
*/
|
|
421
|
+
private getFallbackHandlerContract;
|
|
422
|
+
/**
|
|
423
|
+
* Call the CompatibilityFallbackHandler getMessageHash method
|
|
424
|
+
*
|
|
425
|
+
* @param messageHash The hash of the message
|
|
426
|
+
* @returns Returns the Safe message hash to be signed
|
|
427
|
+
* @link https://github.com/safe-global/safe-contracts/blob/8ffae95faa815acf86ec8b50021ebe9f96abde10/contracts/handler/CompatibilityFallbackHandler.sol#L26-L28
|
|
428
|
+
*/
|
|
429
|
+
getSafeMessageHash: (messageHash: string) => Promise<string>;
|
|
430
|
+
/**
|
|
431
|
+
* Call the CompatibilityFallbackHandler isValidSignature method
|
|
432
|
+
*
|
|
433
|
+
* @param messageHash The hash of the message
|
|
434
|
+
* @param signature The signature to be validated or '0x'. You can send as signature one of the following:
|
|
435
|
+
* 1) An array of SafeSignature. In this case the signatures are concatenated for validation (buildSignatureBytes())
|
|
436
|
+
* 2) The concatenated signatures as string
|
|
437
|
+
* 3) '0x' if you want to validate an onchain message (Approved hash)
|
|
438
|
+
* @returns A boolean indicating if the signature is valid
|
|
439
|
+
* @link https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol
|
|
440
|
+
*/
|
|
441
|
+
isValidSignature: (messageHash: string, signature?: SafeSignature[] | string) => Promise<boolean>;
|
|
392
442
|
}
|
|
393
443
|
export default Safe;
|
package/dist/src/Safe.js
CHANGED
|
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
|
-
var _Safe_predictedSafe, _Safe_ethAdapter, _Safe_contractManager, _Safe_ownerManager, _Safe_moduleManager, _Safe_guardManager, _Safe_fallbackHandlerManager;
|
|
16
|
+
var _Safe_predictedSafe, _Safe_ethAdapter, _Safe_contractManager, _Safe_ownerManager, _Safe_moduleManager, _Safe_guardManager, _Safe_fallbackHandlerManager, _Safe_MAGIC_VALUE, _Safe_MAGIC_VALUE_BYTES;
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
const safe_core_sdk_types_1 = require("@safe-global/safe-core-sdk-types");
|
|
19
19
|
const utils_1 = require("./contracts/utils");
|
|
@@ -23,12 +23,16 @@ const fallbackHandlerManager_1 = __importDefault(require("./managers/fallbackHan
|
|
|
23
23
|
const guardManager_1 = __importDefault(require("./managers/guardManager"));
|
|
24
24
|
const moduleManager_1 = __importDefault(require("./managers/moduleManager"));
|
|
25
25
|
const ownerManager_1 = __importDefault(require("./managers/ownerManager"));
|
|
26
|
+
const types_1 = require("./types");
|
|
26
27
|
const utils_2 = require("./utils");
|
|
27
|
-
const utils_3 = require("./utils/signatures/utils");
|
|
28
28
|
const SafeTransaction_1 = __importDefault(require("./utils/transactions/SafeTransaction"));
|
|
29
|
-
const
|
|
30
|
-
const
|
|
29
|
+
const utils_3 = require("./utils/transactions/utils");
|
|
30
|
+
const types_2 = require("./utils/types");
|
|
31
31
|
const safeDeploymentContracts_1 = require("./contracts/safeDeploymentContracts");
|
|
32
|
+
const SafeMessage_1 = __importDefault(require("./utils/messages/SafeMessage"));
|
|
33
|
+
const satisfies_1 = __importDefault(require("semver/functions/satisfies"));
|
|
34
|
+
const EQ_OR_GT_1_4_1 = '>=1.4.1';
|
|
35
|
+
const EQ_OR_GT_1_3_0 = '>=1.3.0';
|
|
32
36
|
class Safe {
|
|
33
37
|
constructor() {
|
|
34
38
|
_Safe_predictedSafe.set(this, void 0);
|
|
@@ -38,6 +42,75 @@ class Safe {
|
|
|
38
42
|
_Safe_moduleManager.set(this, void 0);
|
|
39
43
|
_Safe_guardManager.set(this, void 0);
|
|
40
44
|
_Safe_fallbackHandlerManager.set(this, void 0);
|
|
45
|
+
_Safe_MAGIC_VALUE.set(this, '0x1626ba7e');
|
|
46
|
+
_Safe_MAGIC_VALUE_BYTES.set(this, '0x20c13b0b'
|
|
47
|
+
/**
|
|
48
|
+
* Creates an instance of the Safe Core SDK.
|
|
49
|
+
* @param config - Ethers Safe configuration
|
|
50
|
+
* @returns The Safe Core SDK instance
|
|
51
|
+
* @throws "The SDK must be initialized with a safeAddress or a predictedSafe"
|
|
52
|
+
* @throws "SafeProxy contract is not deployed on the current network"
|
|
53
|
+
* @throws "MultiSend contract is not deployed on the current network"
|
|
54
|
+
* @throws "MultiSendCallOnly contract is not deployed on the current network"
|
|
55
|
+
*/
|
|
56
|
+
);
|
|
57
|
+
/**
|
|
58
|
+
* Call the CompatibilityFallbackHandler getMessageHash method
|
|
59
|
+
*
|
|
60
|
+
* @param messageHash The hash of the message
|
|
61
|
+
* @returns Returns the Safe message hash to be signed
|
|
62
|
+
* @link https://github.com/safe-global/safe-contracts/blob/8ffae95faa815acf86ec8b50021ebe9f96abde10/contracts/handler/CompatibilityFallbackHandler.sol#L26-L28
|
|
63
|
+
*/
|
|
64
|
+
this.getSafeMessageHash = async (messageHash) => {
|
|
65
|
+
const safeAddress = await this.getAddress();
|
|
66
|
+
const safeVersion = await this.getContractVersion();
|
|
67
|
+
const chainId = await this.getChainId();
|
|
68
|
+
return (0, utils_2.calculateSafeMessageHash)(safeAddress, messageHash, safeVersion, chainId);
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Call the CompatibilityFallbackHandler isValidSignature method
|
|
72
|
+
*
|
|
73
|
+
* @param messageHash The hash of the message
|
|
74
|
+
* @param signature The signature to be validated or '0x'. You can send as signature one of the following:
|
|
75
|
+
* 1) An array of SafeSignature. In this case the signatures are concatenated for validation (buildSignatureBytes())
|
|
76
|
+
* 2) The concatenated signatures as string
|
|
77
|
+
* 3) '0x' if you want to validate an onchain message (Approved hash)
|
|
78
|
+
* @returns A boolean indicating if the signature is valid
|
|
79
|
+
* @link https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol
|
|
80
|
+
*/
|
|
81
|
+
this.isValidSignature = async (messageHash, signature = '0x') => {
|
|
82
|
+
const safeAddress = await this.getAddress();
|
|
83
|
+
const fallbackHandler = await this.getFallbackHandlerContract();
|
|
84
|
+
const signatureToCheck = signature && Array.isArray(signature) ? (0, utils_2.buildSignatureBytes)(signature) : signature;
|
|
85
|
+
const data = fallbackHandler.encode('isValidSignature(bytes32,bytes)', [
|
|
86
|
+
messageHash,
|
|
87
|
+
signatureToCheck
|
|
88
|
+
]);
|
|
89
|
+
const bytesData = fallbackHandler.encode('isValidSignature(bytes,bytes)', [
|
|
90
|
+
messageHash,
|
|
91
|
+
signatureToCheck
|
|
92
|
+
]);
|
|
93
|
+
try {
|
|
94
|
+
const isValidSignatureResponse = await Promise.all([
|
|
95
|
+
__classPrivateFieldGet(this, _Safe_ethAdapter, "f").call({
|
|
96
|
+
from: safeAddress,
|
|
97
|
+
to: safeAddress,
|
|
98
|
+
data: data
|
|
99
|
+
}),
|
|
100
|
+
__classPrivateFieldGet(this, _Safe_ethAdapter, "f").call({
|
|
101
|
+
from: safeAddress,
|
|
102
|
+
to: safeAddress,
|
|
103
|
+
data: bytesData
|
|
104
|
+
})
|
|
105
|
+
]);
|
|
106
|
+
return (!!isValidSignatureResponse.length &&
|
|
107
|
+
(isValidSignatureResponse[0].slice(0, 10).toLowerCase() === __classPrivateFieldGet(this, _Safe_MAGIC_VALUE, "f") ||
|
|
108
|
+
isValidSignatureResponse[1].slice(0, 10).toLowerCase() === __classPrivateFieldGet(this, _Safe_MAGIC_VALUE_BYTES, "f")));
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
41
114
|
}
|
|
42
115
|
/**
|
|
43
116
|
* Creates an instance of the Safe Core SDK.
|
|
@@ -64,7 +137,7 @@ class Safe {
|
|
|
64
137
|
async init(config) {
|
|
65
138
|
const { ethAdapter, isL1SafeSingleton, contractNetworks } = config;
|
|
66
139
|
__classPrivateFieldSet(this, _Safe_ethAdapter, ethAdapter, "f");
|
|
67
|
-
if ((0,
|
|
140
|
+
if ((0, types_2.isSafeConfigWithPredictedSafe)(config)) {
|
|
68
141
|
__classPrivateFieldSet(this, _Safe_predictedSafe, config.predictedSafe, "f");
|
|
69
142
|
__classPrivateFieldSet(this, _Safe_contractManager, await contractManager_1.default.create({
|
|
70
143
|
ethAdapter: __classPrivateFieldGet(this, _Safe_ethAdapter, "f"),
|
|
@@ -142,6 +215,7 @@ class Safe {
|
|
|
142
215
|
const chainId = await __classPrivateFieldGet(this, _Safe_ethAdapter, "f").getChainId();
|
|
143
216
|
return (0, utils_1.predictSafeAddress)({
|
|
144
217
|
ethAdapter: __classPrivateFieldGet(this, _Safe_ethAdapter, "f"),
|
|
218
|
+
chainId,
|
|
145
219
|
customContracts: __classPrivateFieldGet(this, _Safe_contractManager, "f").contractNetworks?.[chainId.toString()],
|
|
146
220
|
...__classPrivateFieldGet(this, _Safe_predictedSafe, "f")
|
|
147
221
|
});
|
|
@@ -322,7 +396,7 @@ class Safe {
|
|
|
322
396
|
const multiSendContract = onlyCalls
|
|
323
397
|
? __classPrivateFieldGet(this, _Safe_contractManager, "f").multiSendCallOnlyContract
|
|
324
398
|
: __classPrivateFieldGet(this, _Safe_contractManager, "f").multiSendContract;
|
|
325
|
-
const multiSendData = (0,
|
|
399
|
+
const multiSendData = (0, utils_3.encodeMultiSendData)(transactions.map(utils_3.standardizeMetaTransactionData));
|
|
326
400
|
const multiSendTransaction = {
|
|
327
401
|
...options,
|
|
328
402
|
to: await multiSendContract.getAddress(),
|
|
@@ -336,7 +410,7 @@ class Safe {
|
|
|
336
410
|
newTransaction = { ...options, ...transactions[0] };
|
|
337
411
|
}
|
|
338
412
|
if (__classPrivateFieldGet(this, _Safe_predictedSafe, "f")) {
|
|
339
|
-
return new SafeTransaction_1.default(await (0,
|
|
413
|
+
return new SafeTransaction_1.default(await (0, utils_3.standardizeSafeTransactionData)({
|
|
340
414
|
predictedSafe: __classPrivateFieldGet(this, _Safe_predictedSafe, "f"),
|
|
341
415
|
ethAdapter: __classPrivateFieldGet(this, _Safe_ethAdapter, "f"),
|
|
342
416
|
tx: newTransaction,
|
|
@@ -346,7 +420,7 @@ class Safe {
|
|
|
346
420
|
if (!__classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract) {
|
|
347
421
|
throw new Error('Safe is not deployed');
|
|
348
422
|
}
|
|
349
|
-
return new SafeTransaction_1.default(await (0,
|
|
423
|
+
return new SafeTransaction_1.default(await (0, utils_3.standardizeSafeTransactionData)({
|
|
350
424
|
safeContract: __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract,
|
|
351
425
|
ethAdapter: __classPrivateFieldGet(this, _Safe_ethAdapter, "f"),
|
|
352
426
|
tx: newTransaction,
|
|
@@ -398,15 +472,13 @@ class Safe {
|
|
|
398
472
|
* Returns the transaction hash of a Safe transaction.
|
|
399
473
|
*
|
|
400
474
|
* @param safeTransaction - The Safe transaction
|
|
401
|
-
* @returns The
|
|
475
|
+
* @returns The hash of the Safe transaction
|
|
402
476
|
*/
|
|
403
477
|
async getTransactionHash(safeTransaction) {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
const txHash = await __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract.getTransactionHash(safeTransactionData);
|
|
409
|
-
return txHash;
|
|
478
|
+
const safeAddress = await this.getAddress();
|
|
479
|
+
const safeVersion = await this.getContractVersion();
|
|
480
|
+
const chainId = await this.getChainId();
|
|
481
|
+
return (0, utils_2.calculateSafeTransactionHash)(safeAddress, safeTransaction.data, safeVersion, chainId);
|
|
410
482
|
}
|
|
411
483
|
/**
|
|
412
484
|
* Signs a hash using the current signer account.
|
|
@@ -414,34 +486,109 @@ class Safe {
|
|
|
414
486
|
* @param hash - The hash to sign
|
|
415
487
|
* @returns The Safe signature
|
|
416
488
|
*/
|
|
417
|
-
async
|
|
418
|
-
|
|
489
|
+
async signHash(hash) {
|
|
490
|
+
const signature = await (0, utils_2.generateSignature)(__classPrivateFieldGet(this, _Safe_ethAdapter, "f"), hash);
|
|
491
|
+
return signature;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Returns a Safe message ready to be signed by the owners.
|
|
495
|
+
*
|
|
496
|
+
* @param message - The message
|
|
497
|
+
* @returns The Safe message
|
|
498
|
+
*/
|
|
499
|
+
createMessage(message) {
|
|
500
|
+
return new SafeMessage_1.default(message);
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Returns the Safe message with a new signature
|
|
504
|
+
*
|
|
505
|
+
* @param message The message to be signed
|
|
506
|
+
* @param signingMethod The signature type
|
|
507
|
+
* @param preimageSafeAddress If the preimage is required, the address of the Safe that will be used to calculate the preimage.
|
|
508
|
+
* This field is mandatory for 1.4.1 contract versions Because the safe uses the old EIP-1271 interface which uses `bytes` instead of `bytes32` for the message
|
|
509
|
+
* we need to use the pre-image of the message to calculate the message hash
|
|
510
|
+
* https://github.com/safe-global/safe-contracts/blob/192c7dc67290940fcbc75165522bb86a37187069/test/core/Safe.Signatures.spec.ts#L229-L233
|
|
511
|
+
* @returns The signed Safe message
|
|
512
|
+
*/
|
|
513
|
+
async signMessage(message, signingMethod = types_1.SigningMethod.ETH_SIGN_TYPED_DATA_V4, preimageSafeAddress) {
|
|
514
|
+
const owners = await this.getOwners();
|
|
515
|
+
const signerAddress = await __classPrivateFieldGet(this, _Safe_ethAdapter, "f").getSignerAddress();
|
|
516
|
+
if (!signerAddress) {
|
|
517
|
+
throw new Error('EthAdapter must be initialized with a signer to use this method');
|
|
518
|
+
}
|
|
519
|
+
const addressIsOwner = owners.some((owner) => signerAddress && (0, utils_2.sameString)(owner, signerAddress));
|
|
520
|
+
if (!addressIsOwner) {
|
|
521
|
+
throw new Error('Messages can only be signed by Safe owners');
|
|
522
|
+
}
|
|
523
|
+
const safeVersion = await this.getContractVersion();
|
|
524
|
+
if (signingMethod === types_1.SigningMethod.SAFE_SIGNATURE &&
|
|
525
|
+
(0, satisfies_1.default)(safeVersion, EQ_OR_GT_1_4_1) &&
|
|
526
|
+
!preimageSafeAddress) {
|
|
527
|
+
throw new Error('The parent Safe account address is mandatory for contract signatures');
|
|
528
|
+
}
|
|
529
|
+
let signature;
|
|
530
|
+
if (signingMethod === types_1.SigningMethod.ETH_SIGN_TYPED_DATA_V4) {
|
|
531
|
+
signature = await this.signTypedData(message, 'v4');
|
|
532
|
+
}
|
|
533
|
+
else if (signingMethod === types_1.SigningMethod.ETH_SIGN_TYPED_DATA_V3) {
|
|
534
|
+
signature = await this.signTypedData(message, 'v3');
|
|
535
|
+
}
|
|
536
|
+
else if (signingMethod === types_1.SigningMethod.ETH_SIGN_TYPED_DATA) {
|
|
537
|
+
signature = await this.signTypedData(message, undefined);
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
const chainId = await this.getChainId();
|
|
541
|
+
if (!(0, utils_2.hasSafeFeature)(utils_2.SAFE_FEATURES.ETH_SIGN, safeVersion)) {
|
|
542
|
+
throw new Error('eth_sign is only supported by Safes >= v1.1.0');
|
|
543
|
+
}
|
|
544
|
+
let safeMessageHash;
|
|
545
|
+
if (signingMethod === types_1.SigningMethod.SAFE_SIGNATURE &&
|
|
546
|
+
preimageSafeAddress &&
|
|
547
|
+
(0, satisfies_1.default)(safeVersion, EQ_OR_GT_1_4_1)) {
|
|
548
|
+
const messageHashData = (0, utils_2.preimageSafeMessageHash)(preimageSafeAddress, (0, utils_2.hashSafeMessage)(message.data), safeVersion, chainId);
|
|
549
|
+
safeMessageHash = await this.getSafeMessageHash(messageHashData);
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
safeMessageHash = await this.getSafeMessageHash((0, utils_2.hashSafeMessage)(message.data));
|
|
553
|
+
}
|
|
554
|
+
signature = await this.signHash(safeMessageHash);
|
|
555
|
+
}
|
|
556
|
+
const signedSafeMessage = this.createMessage(message.data);
|
|
557
|
+
message.signatures.forEach((signature) => {
|
|
558
|
+
signedSafeMessage.addSignature(signature);
|
|
559
|
+
});
|
|
560
|
+
signedSafeMessage.addSignature(signature);
|
|
561
|
+
return signedSafeMessage;
|
|
419
562
|
}
|
|
420
563
|
/**
|
|
421
564
|
* Signs a transaction according to the EIP-712 using the current signer account.
|
|
422
565
|
*
|
|
423
|
-
* @param
|
|
566
|
+
* @param eip712Data - The Safe Transaction or message hash to be signed
|
|
424
567
|
* @param methodVersion - EIP-712 version. Optional
|
|
425
568
|
* @returns The Safe signature
|
|
426
569
|
*/
|
|
427
|
-
async signTypedData(
|
|
428
|
-
const
|
|
570
|
+
async signTypedData(eip712Data, methodVersion) {
|
|
571
|
+
const safeEIP712Args = {
|
|
429
572
|
safeAddress: await this.getAddress(),
|
|
430
573
|
safeVersion: await this.getContractVersion(),
|
|
431
574
|
chainId: await this.getEthAdapter().getChainId(),
|
|
432
|
-
|
|
575
|
+
data: eip712Data.data
|
|
433
576
|
};
|
|
434
|
-
return (0,
|
|
577
|
+
return (0, utils_2.generateEIP712Signature)(__classPrivateFieldGet(this, _Safe_ethAdapter, "f"), safeEIP712Args, methodVersion);
|
|
435
578
|
}
|
|
436
579
|
/**
|
|
437
580
|
* Adds the signature of the current signer to the Safe transaction object.
|
|
438
581
|
*
|
|
439
582
|
* @param safeTransaction - The Safe transaction to be signed
|
|
440
583
|
* @param signingMethod - Method followed to sign a transaction. Optional. Default value is "eth_sign"
|
|
584
|
+
* @param preimageSafeAddress - If the preimage is required, the address of the Safe that will be used to calculate the preimage
|
|
585
|
+
* This field is mandatory for 1.3.0 and 1.4.1 contract versions Because the safe uses the old EIP-1271 interface which uses `bytes` instead of `bytes32` for the message
|
|
586
|
+
* we need to use the pre-image of the message to calculate the message hash
|
|
587
|
+
* https://github.com/safe-global/safe-contracts/blob/192c7dc67290940fcbc75165522bb86a37187069/test/core/Safe.Signatures.spec.ts#L229-L233
|
|
441
588
|
* @returns The signed Safe transaction
|
|
442
589
|
* @throws "Transactions can only be signed by Safe owners"
|
|
443
590
|
*/
|
|
444
|
-
async signTransaction(safeTransaction, signingMethod =
|
|
591
|
+
async signTransaction(safeTransaction, signingMethod = types_1.SigningMethod.ETH_SIGN_TYPED_DATA_V4, preimageSafeAddress) {
|
|
445
592
|
const transaction = (0, utils_2.isSafeMultisigTransactionResponse)(safeTransaction)
|
|
446
593
|
? await this.toSafeTransactionType(safeTransaction)
|
|
447
594
|
: safeTransaction;
|
|
@@ -454,23 +601,42 @@ class Safe {
|
|
|
454
601
|
if (!addressIsOwner) {
|
|
455
602
|
throw new Error('Transactions can only be signed by Safe owners');
|
|
456
603
|
}
|
|
604
|
+
const safeVersion = await this.getContractVersion();
|
|
605
|
+
if (signingMethod === types_1.SigningMethod.SAFE_SIGNATURE &&
|
|
606
|
+
(0, satisfies_1.default)(safeVersion, EQ_OR_GT_1_3_0) &&
|
|
607
|
+
!preimageSafeAddress) {
|
|
608
|
+
throw new Error('The parent Safe account address is mandatory for contract signatures');
|
|
609
|
+
}
|
|
457
610
|
let signature;
|
|
458
|
-
if (signingMethod ===
|
|
611
|
+
if (signingMethod === types_1.SigningMethod.ETH_SIGN_TYPED_DATA_V4) {
|
|
459
612
|
signature = await this.signTypedData(transaction, 'v4');
|
|
460
613
|
}
|
|
461
|
-
else if (signingMethod ===
|
|
614
|
+
else if (signingMethod === types_1.SigningMethod.ETH_SIGN_TYPED_DATA_V3) {
|
|
462
615
|
signature = await this.signTypedData(transaction, 'v3');
|
|
463
616
|
}
|
|
464
|
-
else if (signingMethod ===
|
|
465
|
-
signature = await this.signTypedData(transaction);
|
|
617
|
+
else if (signingMethod === types_1.SigningMethod.ETH_SIGN_TYPED_DATA) {
|
|
618
|
+
signature = await this.signTypedData(transaction, undefined);
|
|
466
619
|
}
|
|
467
620
|
else {
|
|
468
621
|
const safeVersion = await this.getContractVersion();
|
|
622
|
+
const chainId = await this.getChainId();
|
|
469
623
|
if (!(0, utils_2.hasSafeFeature)(utils_2.SAFE_FEATURES.ETH_SIGN, safeVersion)) {
|
|
470
624
|
throw new Error('eth_sign is only supported by Safes >= v1.1.0');
|
|
471
625
|
}
|
|
472
|
-
|
|
473
|
-
|
|
626
|
+
let txHash;
|
|
627
|
+
// IMPORTANT: because the safe uses the old EIP-1271 interface which uses `bytes` instead of `bytes32` for the message
|
|
628
|
+
// we need to use the pre-image of the transaction hash to calculate the message hash
|
|
629
|
+
// https://github.com/safe-global/safe-contracts/blob/192c7dc67290940fcbc75165522bb86a37187069/test/core/Safe.Signatures.spec.ts#L229-L233
|
|
630
|
+
if (signingMethod === types_1.SigningMethod.SAFE_SIGNATURE &&
|
|
631
|
+
(0, satisfies_1.default)(safeVersion, EQ_OR_GT_1_3_0) &&
|
|
632
|
+
preimageSafeAddress) {
|
|
633
|
+
const txHashData = (0, utils_2.preimageSafeTransactionHash)(preimageSafeAddress, safeTransaction.data, safeVersion, chainId);
|
|
634
|
+
txHash = await this.getSafeMessageHash(txHashData);
|
|
635
|
+
}
|
|
636
|
+
else {
|
|
637
|
+
txHash = await this.getTransactionHash(transaction);
|
|
638
|
+
}
|
|
639
|
+
signature = await this.signHash(txHash);
|
|
474
640
|
}
|
|
475
641
|
const signedSafeTransaction = await this.copyTransaction(transaction);
|
|
476
642
|
signedSafeTransaction.addSignature(signature);
|
|
@@ -791,7 +957,7 @@ class Safe {
|
|
|
791
957
|
const txHash = await this.getTransactionHash(signedSafeTransaction);
|
|
792
958
|
const ownersWhoApprovedTx = await this.getOwnersWhoApprovedTx(txHash);
|
|
793
959
|
for (const owner of ownersWhoApprovedTx) {
|
|
794
|
-
signedSafeTransaction.addSignature((0,
|
|
960
|
+
signedSafeTransaction.addSignature((0, utils_2.generatePreValidatedSignature)(owner));
|
|
795
961
|
}
|
|
796
962
|
const owners = await this.getOwners();
|
|
797
963
|
const signerAddress = await __classPrivateFieldGet(this, _Safe_ethAdapter, "f").getSignerAddress();
|
|
@@ -799,7 +965,7 @@ class Safe {
|
|
|
799
965
|
throw new Error('EthAdapter must be initialized with a signer to use this method');
|
|
800
966
|
}
|
|
801
967
|
if (owners.includes(signerAddress)) {
|
|
802
|
-
signedSafeTransaction.addSignature((0,
|
|
968
|
+
signedSafeTransaction.addSignature((0, utils_2.generatePreValidatedSignature)(signerAddress));
|
|
803
969
|
}
|
|
804
970
|
const isTxValid = await __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract.isValidTransaction(signedSafeTransaction, {
|
|
805
971
|
from: signerAddress,
|
|
@@ -828,7 +994,7 @@ class Safe {
|
|
|
828
994
|
const txHash = await this.getTransactionHash(signedSafeTransaction);
|
|
829
995
|
const ownersWhoApprovedTx = await this.getOwnersWhoApprovedTx(txHash);
|
|
830
996
|
for (const owner of ownersWhoApprovedTx) {
|
|
831
|
-
signedSafeTransaction.addSignature((0,
|
|
997
|
+
signedSafeTransaction.addSignature((0, utils_2.generatePreValidatedSignature)(owner));
|
|
832
998
|
}
|
|
833
999
|
const owners = await this.getOwners();
|
|
834
1000
|
const threshold = await this.getThreshold();
|
|
@@ -836,7 +1002,7 @@ class Safe {
|
|
|
836
1002
|
if (threshold > signedSafeTransaction.signatures.size &&
|
|
837
1003
|
signerAddress &&
|
|
838
1004
|
owners.includes(signerAddress)) {
|
|
839
|
-
signedSafeTransaction.addSignature((0,
|
|
1005
|
+
signedSafeTransaction.addSignature((0, utils_2.generatePreValidatedSignature)(signerAddress));
|
|
840
1006
|
}
|
|
841
1007
|
if (threshold > signedSafeTransaction.signatures.size) {
|
|
842
1008
|
const signaturesMissing = threshold - signedSafeTransaction.signatures.size;
|
|
@@ -979,13 +1145,13 @@ class Safe {
|
|
|
979
1145
|
safeDeploymentConfig?.saltNonce ||
|
|
980
1146
|
(0, utils_1.getChainSpecificDefaultSaltNonce)(chainId);
|
|
981
1147
|
const safeDeployTransactionData = {
|
|
982
|
-
...transactionOptions,
|
|
1148
|
+
...transactionOptions, // optional transaction options like from, gasLimit, gasPrice...
|
|
983
1149
|
to: await safeProxyFactoryContract.getAddress(),
|
|
984
1150
|
value: '0',
|
|
985
1151
|
// we use the createProxyWithNonce method to create the Safe in a deterministic address, see: https://github.com/safe-global/safe-contracts/blob/main/contracts/proxies/SafeProxyFactory.sol#L52
|
|
986
1152
|
data: safeProxyFactoryContract.encode('createProxyWithNonce', [
|
|
987
1153
|
await safeSingletonContract.getAddress(),
|
|
988
|
-
initializer,
|
|
1154
|
+
initializer, // call to the setup method to set the threshold & owners of the new Safe
|
|
989
1155
|
saltNonce
|
|
990
1156
|
])
|
|
991
1157
|
};
|
|
@@ -1012,17 +1178,35 @@ class Safe {
|
|
|
1012
1178
|
});
|
|
1013
1179
|
// multiSend method with the transactions encoded
|
|
1014
1180
|
const batchData = multiSendCallOnlyContract.encode('multiSend', [
|
|
1015
|
-
(0,
|
|
1181
|
+
(0, utils_3.encodeMultiSendData)(transactions) // encoded transactions
|
|
1016
1182
|
]);
|
|
1017
1183
|
const transactionBatch = {
|
|
1018
|
-
...transactionOptions,
|
|
1184
|
+
...transactionOptions, // optional transaction options like from, gasLimit, gasPrice...
|
|
1019
1185
|
to: await multiSendCallOnlyContract.getAddress(),
|
|
1020
1186
|
value: '0',
|
|
1021
1187
|
data: batchData
|
|
1022
1188
|
};
|
|
1023
1189
|
return transactionBatch;
|
|
1024
1190
|
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Get the fallback handler contract
|
|
1193
|
+
*
|
|
1194
|
+
* @returns The fallback Handler contract
|
|
1195
|
+
*/
|
|
1196
|
+
async getFallbackHandlerContract() {
|
|
1197
|
+
if (!__classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract) {
|
|
1198
|
+
throw new Error('Safe is not deployed');
|
|
1199
|
+
}
|
|
1200
|
+
const safeVersion = (await __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract.getVersion()) ?? config_1.DEFAULT_SAFE_VERSION;
|
|
1201
|
+
const chainId = await __classPrivateFieldGet(this, _Safe_ethAdapter, "f").getChainId();
|
|
1202
|
+
const compatibilityFallbackHandlerContract = await (0, safeDeploymentContracts_1.getCompatibilityFallbackHandlerContract)({
|
|
1203
|
+
ethAdapter: __classPrivateFieldGet(this, _Safe_ethAdapter, "f"),
|
|
1204
|
+
safeVersion,
|
|
1205
|
+
customContracts: __classPrivateFieldGet(this, _Safe_contractManager, "f").contractNetworks?.[chainId.toString()]
|
|
1206
|
+
});
|
|
1207
|
+
return compatibilityFallbackHandlerContract;
|
|
1208
|
+
}
|
|
1025
1209
|
}
|
|
1026
|
-
_Safe_predictedSafe = new WeakMap(), _Safe_ethAdapter = new WeakMap(), _Safe_contractManager = new WeakMap(), _Safe_ownerManager = new WeakMap(), _Safe_moduleManager = new WeakMap(), _Safe_guardManager = new WeakMap(), _Safe_fallbackHandlerManager = new WeakMap();
|
|
1210
|
+
_Safe_predictedSafe = new WeakMap(), _Safe_ethAdapter = new WeakMap(), _Safe_contractManager = new WeakMap(), _Safe_ownerManager = new WeakMap(), _Safe_moduleManager = new WeakMap(), _Safe_guardManager = new WeakMap(), _Safe_fallbackHandlerManager = new WeakMap(), _Safe_MAGIC_VALUE = new WeakMap(), _Safe_MAGIC_VALUE_BYTES = new WeakMap();
|
|
1027
1211
|
exports.default = Safe;
|
|
1028
1212
|
//# sourceMappingURL=Safe.js.map
|