@safe-global/protocol-kit
Advanced tools
Comparing version 4.0.0-alpha.0 to 4.0.0
@@ -58,7 +58,7 @@ "use strict"; | ||
defaultAbi; // if no customAbi and no abi is present in the safe-deployments we use our hardcoded abi | ||
this.runner = runner; | ||
this.runner = runner || safeProvider.getExternalProvider(); | ||
this.safeProvider = safeProvider; | ||
} | ||
async init() { | ||
this.contract = new ethers_1.Contract(this.contractAddress, this.contractAbi, this.runner || (await this.safeProvider.getExternalSigner())); | ||
this.contract = new ethers_1.Contract(this.contractAddress, this.contractAbi, (await this.safeProvider.getExternalSigner()) || this.runner); | ||
} | ||
@@ -65,0 +65,0 @@ } |
@@ -48,3 +48,2 @@ /// <reference types="node" /> | ||
export declare function zkSyncEraCreate2Address(from: string, safeVersion: SafeVersion, salt: Buffer, input: string): string; | ||
export declare function sameString(str1: string, str2: string): boolean; | ||
export declare function toTxResult(transactionResponse: ContractTransactionResponse, options?: TransactionOptions): TransactionResult; | ||
@@ -51,0 +50,0 @@ export declare function isTypedDataSigner(signer: any): signer is AbstractSigner; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isSignerCompatible = exports.isTypedDataSigner = exports.toTxResult = exports.sameString = exports.zkSyncEraCreate2Address = exports.validateSafeDeploymentConfig = exports.validateSafeAccountConfig = exports.predictSafeAddress = exports.getPredictedSafeAddressInitCode = exports.getChainSpecificDefaultSaltNonce = exports.encodeSetupCallData = exports.encodeCreateProxyWithNonce = exports.PREDETERMINED_SALT_NONCE = void 0; | ||
exports.isSignerCompatible = exports.isTypedDataSigner = exports.toTxResult = exports.zkSyncEraCreate2Address = exports.validateSafeDeploymentConfig = exports.validateSafeAccountConfig = exports.predictSafeAddress = exports.getPredictedSafeAddressInitCode = exports.getChainSpecificDefaultSaltNonce = exports.encodeSetupCallData = exports.encodeCreateProxyWithNonce = exports.PREDETERMINED_SALT_NONCE = void 0; | ||
const ethers_1 = require("ethers"); | ||
@@ -218,6 +218,2 @@ const sha3_1 = require("@noble/hashes/sha3"); | ||
exports.zkSyncEraCreate2Address = zkSyncEraCreate2Address; | ||
function sameString(str1, str2) { | ||
return str1.toLowerCase() === str2.toLowerCase(); | ||
} | ||
exports.sameString = sameString; | ||
function toTxResult(transactionResponse, options) { | ||
@@ -224,0 +220,0 @@ return { |
@@ -5,4 +5,3 @@ import { ContractNetworksConfig, MultiSendCallOnlyContractImplementationType, MultiSendContractImplementationType, SafeConfig, SafeContractImplementationType } from '../types'; | ||
#private; | ||
static create(config: SafeConfig, safeProvider: SafeProvider): Promise<ContractManager>; | ||
init(config: SafeConfig, safeProvider: SafeProvider): Promise<void>; | ||
static init(config: SafeConfig, safeProvider: SafeProvider): Promise<ContractManager>; | ||
get contractNetworks(): ContractNetworksConfig | undefined; | ||
@@ -9,0 +8,0 @@ get isL1SafeSingleton(): boolean | undefined; |
"use strict"; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
@@ -8,8 +13,3 @@ if (kind === "m") throw new TypeError("Private method is not writable"); | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var _ContractManager_contractNetworks, _ContractManager_isL1SafeSingleton, _ContractManager_safeContract, _ContractManager_multiSendContract, _ContractManager_multiSendCallOnlyContract; | ||
var _ContractManager_instances, _ContractManager_contractNetworks, _ContractManager_isL1SafeSingleton, _ContractManager_safeContract, _ContractManager_multiSendContract, _ContractManager_multiSendCallOnlyContract, _ContractManager_initializeContractManager; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -21,2 +21,3 @@ const config_1 = require("../contracts/config"); | ||
constructor() { | ||
_ContractManager_instances.add(this); | ||
_ContractManager_contractNetworks.set(this, void 0); | ||
@@ -28,51 +29,7 @@ _ContractManager_isL1SafeSingleton.set(this, void 0); | ||
} | ||
static async create(config, safeProvider) { | ||
static async init(config, safeProvider) { | ||
const contractManager = new ContractManager(); | ||
await contractManager.init(config, safeProvider); | ||
await __classPrivateFieldGet(contractManager, _ContractManager_instances, "m", _ContractManager_initializeContractManager).call(contractManager, config, safeProvider); | ||
return contractManager; | ||
} | ||
async init(config, safeProvider) { | ||
const { isL1SafeSingleton, contractNetworks, predictedSafe, safeAddress } = config; | ||
const chainId = await safeProvider.getChainId(); | ||
const customContracts = contractNetworks?.[chainId.toString()]; | ||
__classPrivateFieldSet(this, _ContractManager_contractNetworks, contractNetworks, "f"); | ||
__classPrivateFieldSet(this, _ContractManager_isL1SafeSingleton, isL1SafeSingleton, "f"); | ||
let safeVersion; | ||
if ((0, types_1.isSafeConfigWithPredictedSafe)(config)) { | ||
safeVersion = predictedSafe?.safeDeploymentConfig?.safeVersion ?? config_1.DEFAULT_SAFE_VERSION; | ||
} | ||
else { | ||
// We use the default version of the Safe contract to get the correct version of this Safe | ||
const defaultSafeContractInstance = await (0, safeDeploymentContracts_1.getSafeContract)({ | ||
safeProvider, | ||
safeVersion: config_1.DEFAULT_SAFE_VERSION, | ||
isL1SafeSingleton, | ||
customSafeAddress: safeAddress, | ||
customContracts | ||
}); | ||
// We check the correct version of the Safe from the blockchain | ||
safeVersion = await defaultSafeContractInstance.getVersion(); | ||
// We get the correct Safe Contract if the real Safe version is not the lastest | ||
const isTheDefaultSafeVersion = safeVersion === config_1.DEFAULT_SAFE_VERSION; | ||
__classPrivateFieldSet(this, _ContractManager_safeContract, isTheDefaultSafeVersion | ||
? defaultSafeContractInstance | ||
: await (0, safeDeploymentContracts_1.getSafeContract)({ | ||
safeProvider, | ||
safeVersion, | ||
isL1SafeSingleton, | ||
customSafeAddress: safeAddress, | ||
customContracts | ||
}), "f"); | ||
} | ||
__classPrivateFieldSet(this, _ContractManager_multiSendContract, await (0, safeDeploymentContracts_1.getMultiSendContract)({ | ||
safeProvider, | ||
safeVersion, | ||
customContracts | ||
}), "f"); | ||
__classPrivateFieldSet(this, _ContractManager_multiSendCallOnlyContract, await (0, safeDeploymentContracts_1.getMultiSendCallOnlyContract)({ | ||
safeProvider, | ||
safeVersion, | ||
customContracts | ||
}), "f"); | ||
} | ||
get contractNetworks() { | ||
@@ -94,4 +51,47 @@ return __classPrivateFieldGet(this, _ContractManager_contractNetworks, "f"); | ||
} | ||
_ContractManager_contractNetworks = new WeakMap(), _ContractManager_isL1SafeSingleton = new WeakMap(), _ContractManager_safeContract = new WeakMap(), _ContractManager_multiSendContract = new WeakMap(), _ContractManager_multiSendCallOnlyContract = new WeakMap(); | ||
_ContractManager_contractNetworks = new WeakMap(), _ContractManager_isL1SafeSingleton = new WeakMap(), _ContractManager_safeContract = new WeakMap(), _ContractManager_multiSendContract = new WeakMap(), _ContractManager_multiSendCallOnlyContract = new WeakMap(), _ContractManager_instances = new WeakSet(), _ContractManager_initializeContractManager = async function _ContractManager_initializeContractManager(config, safeProvider) { | ||
const { isL1SafeSingleton, contractNetworks, predictedSafe, safeAddress } = config; | ||
const chainId = await safeProvider.getChainId(); | ||
const customContracts = contractNetworks?.[chainId.toString()]; | ||
__classPrivateFieldSet(this, _ContractManager_contractNetworks, contractNetworks, "f"); | ||
__classPrivateFieldSet(this, _ContractManager_isL1SafeSingleton, isL1SafeSingleton, "f"); | ||
let safeVersion; | ||
if ((0, types_1.isSafeConfigWithPredictedSafe)(config)) { | ||
safeVersion = predictedSafe?.safeDeploymentConfig?.safeVersion ?? config_1.DEFAULT_SAFE_VERSION; | ||
} | ||
else { | ||
// We use the default version of the Safe contract to get the correct version of this Safe | ||
const defaultSafeContractInstance = await (0, safeDeploymentContracts_1.getSafeContract)({ | ||
safeProvider, | ||
safeVersion: config_1.DEFAULT_SAFE_VERSION, | ||
isL1SafeSingleton, | ||
customSafeAddress: safeAddress, | ||
customContracts | ||
}); | ||
// We check the correct version of the Safe from the blockchain | ||
safeVersion = await defaultSafeContractInstance.getVersion(); | ||
// We get the correct Safe Contract if the real Safe version is not the lastest | ||
const isTheDefaultSafeVersion = safeVersion === config_1.DEFAULT_SAFE_VERSION; | ||
__classPrivateFieldSet(this, _ContractManager_safeContract, isTheDefaultSafeVersion | ||
? defaultSafeContractInstance | ||
: await (0, safeDeploymentContracts_1.getSafeContract)({ | ||
safeProvider, | ||
safeVersion, | ||
isL1SafeSingleton, | ||
customSafeAddress: safeAddress, | ||
customContracts | ||
}), "f"); | ||
} | ||
__classPrivateFieldSet(this, _ContractManager_multiSendContract, await (0, safeDeploymentContracts_1.getMultiSendContract)({ | ||
safeProvider, | ||
safeVersion, | ||
customContracts | ||
}), "f"); | ||
__classPrivateFieldSet(this, _ContractManager_multiSendCallOnlyContract, await (0, safeDeploymentContracts_1.getMultiSendCallOnlyContract)({ | ||
safeProvider, | ||
safeVersion, | ||
customContracts | ||
}), "f"); | ||
}; | ||
exports.default = ContractManager; | ||
//# sourceMappingURL=contractManager.js.map |
@@ -15,3 +15,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const address_1 = require("../utils/address"); | ||
const utils_1 = require("../utils"); | ||
const constants_1 = require("../utils/constants"); | ||
@@ -27,3 +27,3 @@ class ModuleManager { | ||
const isValidAddress = __classPrivateFieldGet(this, _ModuleManager_safeProvider, "f").isAddress(moduleAddress); | ||
if (!isValidAddress || (0, address_1.isRestrictedAddress)(moduleAddress)) { | ||
if (!isValidAddress || (0, utils_1.isRestrictedAddress)(moduleAddress)) { | ||
throw new Error('Invalid module address provided'); | ||
@@ -33,3 +33,3 @@ } | ||
validateModuleIsNotEnabled(moduleAddress, modules) { | ||
const moduleIndex = modules.findIndex((module) => (0, address_1.sameString)(module, moduleAddress)); | ||
const moduleIndex = modules.findIndex((module) => (0, utils_1.sameString)(module, moduleAddress)); | ||
const isEnabled = moduleIndex >= 0; | ||
@@ -41,3 +41,3 @@ if (isEnabled) { | ||
validateModuleIsEnabled(moduleAddress, modules) { | ||
const moduleIndex = modules.findIndex((module) => (0, address_1.sameString)(module, moduleAddress)); | ||
const moduleIndex = modules.findIndex((module) => (0, utils_1.sameString)(module, moduleAddress)); | ||
const isEnabled = moduleIndex >= 0; | ||
@@ -44,0 +44,0 @@ if (!isEnabled) { |
@@ -15,3 +15,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const address_1 = require("../utils/address"); | ||
const utils_1 = require("../utils"); | ||
const constants_1 = require("../utils/constants"); | ||
@@ -27,3 +27,3 @@ class OwnerManager { | ||
const isValidAddress = __classPrivateFieldGet(this, _OwnerManager_safeProvider, "f").isAddress(ownerAddress); | ||
if (!isValidAddress || (0, address_1.isRestrictedAddress)(ownerAddress)) { | ||
if (!isValidAddress || (0, utils_1.isRestrictedAddress)(ownerAddress)) { | ||
throw new Error(errorMessage || 'Invalid owner address provided'); | ||
@@ -41,3 +41,3 @@ } | ||
validateAddressIsNotOwner(ownerAddress, owners, errorMessage) { | ||
const ownerIndex = owners.findIndex((owner) => (0, address_1.sameString)(owner, ownerAddress)); | ||
const ownerIndex = owners.findIndex((owner) => (0, utils_1.sameString)(owner, ownerAddress)); | ||
const isOwner = ownerIndex >= 0; | ||
@@ -49,3 +49,3 @@ if (isOwner) { | ||
validateAddressIsOwner(ownerAddress, owners, errorMessage) { | ||
const ownerIndex = owners.findIndex((owner) => (0, address_1.sameString)(owner, ownerAddress)); | ||
const ownerIndex = owners.findIndex((owner) => (0, utils_1.sameString)(owner, ownerAddress)); | ||
const isOwner = ownerIndex >= 0; | ||
@@ -52,0 +52,0 @@ if (!isOwner) { |
@@ -18,13 +18,4 @@ import { SafeMultisigTransactionResponse, SafeSignature, SafeTransaction, SafeVersion, TransactionOptions, TransactionResult, MetaTransactionData, Transaction, EIP712TypedData } from '@safe-global/safe-core-sdk-types'; | ||
*/ | ||
static create(config: SafeConfig): Promise<Safe>; | ||
static init(config: SafeConfig): Promise<Safe>; | ||
/** | ||
* Initializes the Safe Core SDK instance. | ||
* @param config - Safe configuration | ||
* @throws "Signer must be connected to a provider" | ||
* @throws "SafeProxy contract is not deployed on the current network" | ||
* @throws "MultiSend contract is not deployed on the current network" | ||
* @throws "MultiSendCallOnly contract is not deployed on the current network" | ||
*/ | ||
private init; | ||
/** | ||
* Returns a new instance of the Safe Core SDK. | ||
@@ -433,8 +424,2 @@ * @param config - Connect Safe configuration | ||
/** | ||
* Get the fallback handler contract | ||
* | ||
* @returns The fallback Handler contract | ||
*/ | ||
private getFallbackHandlerContract; | ||
/** | ||
* Call the CompatibilityFallbackHandler getMessageHash method | ||
@@ -441,0 +426,0 @@ * |
"use strict"; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
@@ -8,11 +13,6 @@ if (kind === "m") throw new TypeError("Private method is not writable"); | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var _Safe_predictedSafe, _Safe_safeProvider, _Safe_contractManager, _Safe_ownerManager, _Safe_moduleManager, _Safe_guardManager, _Safe_fallbackHandlerManager, _Safe_MAGIC_VALUE, _Safe_MAGIC_VALUE_BYTES; | ||
var _Safe_instances, _Safe_predictedSafe, _Safe_safeProvider, _Safe_contractManager, _Safe_ownerManager, _Safe_moduleManager, _Safe_guardManager, _Safe_fallbackHandlerManager, _Safe_MAGIC_VALUE, _Safe_MAGIC_VALUE_BYTES, _Safe_initializeProtocolKit, _Safe_getFallbackHandlerContract; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -40,2 +40,3 @@ const safe_core_sdk_types_1 = require("@safe-global/safe-core-sdk-types"); | ||
constructor() { | ||
_Safe_instances.add(this); | ||
_Safe_predictedSafe.set(this, void 0); | ||
@@ -86,3 +87,3 @@ _Safe_safeProvider.set(this, void 0); | ||
const safeAddress = await this.getAddress(); | ||
const fallbackHandler = await this.getFallbackHandlerContract(); | ||
const fallbackHandler = await __classPrivateFieldGet(this, _Safe_instances, "m", _Safe_getFallbackHandlerContract).call(this); | ||
const signatureToCheck = signature && Array.isArray(signature) ? (0, utils_2.buildSignatureBytes)(signature) : signature; | ||
@@ -130,44 +131,8 @@ // @ts-expect-error Argument of type isValidSignature(bytes32,bytes) is not assignable to parameter of type isValidSignature | ||
*/ | ||
static async create(config) { | ||
const safeSdk = new Safe(); | ||
await safeSdk.init(config); | ||
return safeSdk; | ||
static async init(config) { | ||
const protocolKit = new Safe(); | ||
await __classPrivateFieldGet(protocolKit, _Safe_instances, "m", _Safe_initializeProtocolKit).call(protocolKit, config); | ||
return protocolKit; | ||
} | ||
/** | ||
* Initializes the Safe Core SDK instance. | ||
* @param config - Safe configuration | ||
* @throws "Signer must be connected to a provider" | ||
* @throws "SafeProxy contract is not deployed on the current network" | ||
* @throws "MultiSend contract is not deployed on the current network" | ||
* @throws "MultiSendCallOnly contract is not deployed on the current network" | ||
*/ | ||
async init(config) { | ||
const { provider, signer, isL1SafeSingleton, contractNetworks } = config; | ||
__classPrivateFieldSet(this, _Safe_safeProvider, new SafeProvider_1.default({ | ||
provider, | ||
signer | ||
}), "f"); | ||
if ((0, types_2.isSafeConfigWithPredictedSafe)(config)) { | ||
__classPrivateFieldSet(this, _Safe_predictedSafe, config.predictedSafe, "f"); | ||
__classPrivateFieldSet(this, _Safe_contractManager, await contractManager_1.default.create({ | ||
provider, | ||
predictedSafe: __classPrivateFieldGet(this, _Safe_predictedSafe, "f"), | ||
isL1SafeSingleton, | ||
contractNetworks | ||
}, __classPrivateFieldGet(this, _Safe_safeProvider, "f")), "f"); | ||
} | ||
else { | ||
__classPrivateFieldSet(this, _Safe_contractManager, await contractManager_1.default.create({ | ||
provider, | ||
safeAddress: config.safeAddress, | ||
isL1SafeSingleton, | ||
contractNetworks | ||
}, __classPrivateFieldGet(this, _Safe_safeProvider, "f")), "f"); | ||
} | ||
__classPrivateFieldSet(this, _Safe_ownerManager, new ownerManager_1.default(__classPrivateFieldGet(this, _Safe_safeProvider, "f"), __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract), "f"); | ||
__classPrivateFieldSet(this, _Safe_moduleManager, new moduleManager_1.default(__classPrivateFieldGet(this, _Safe_safeProvider, "f"), __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract), "f"); | ||
__classPrivateFieldSet(this, _Safe_guardManager, new guardManager_1.default(__classPrivateFieldGet(this, _Safe_safeProvider, "f"), __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract), "f"); | ||
__classPrivateFieldSet(this, _Safe_fallbackHandlerManager, new fallbackHandlerManager_1.default(__classPrivateFieldGet(this, _Safe_safeProvider, "f"), __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract), "f"); | ||
} | ||
/** | ||
* Returns a new instance of the Safe Core SDK. | ||
@@ -190,3 +155,3 @@ * @param config - Connect Safe configuration | ||
if (safeAddress) { | ||
return await Safe.create({ | ||
return await Safe.init({ | ||
safeAddress, | ||
@@ -198,3 +163,3 @@ ...configProps | ||
if (predictedSafe) { | ||
return await Safe.create({ | ||
return await Safe.init({ | ||
predictedSafe, | ||
@@ -206,3 +171,3 @@ ...configProps | ||
if (__classPrivateFieldGet(this, _Safe_predictedSafe, "f")) { | ||
return await Safe.create({ | ||
return await Safe.init({ | ||
predictedSafe: __classPrivateFieldGet(this, _Safe_predictedSafe, "f"), | ||
@@ -213,3 +178,3 @@ ...configProps | ||
// The previous existing Safe is connected to a new Signer | ||
return await Safe.create({ | ||
return await Safe.init({ | ||
safeAddress: await this.getAddress(), | ||
@@ -1229,23 +1194,59 @@ ...configProps | ||
} | ||
/** | ||
* Get the fallback handler contract | ||
* | ||
* @returns The fallback Handler contract | ||
*/ | ||
async getFallbackHandlerContract() { | ||
if (!__classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract) { | ||
throw new Error('Safe is not deployed'); | ||
} | ||
const safeVersion = (await __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract.getVersion()) ?? config_1.DEFAULT_SAFE_VERSION; | ||
const chainId = await __classPrivateFieldGet(this, _Safe_safeProvider, "f").getChainId(); | ||
const compatibilityFallbackHandlerContract = await (0, safeDeploymentContracts_1.getCompatibilityFallbackHandlerContract)({ | ||
safeProvider: __classPrivateFieldGet(this, _Safe_safeProvider, "f"), | ||
safeVersion, | ||
customContracts: __classPrivateFieldGet(this, _Safe_contractManager, "f").contractNetworks?.[chainId.toString()] | ||
}); | ||
return compatibilityFallbackHandlerContract; | ||
} | ||
_Safe_predictedSafe = new WeakMap(), _Safe_safeProvider = 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(), _Safe_instances = new WeakSet(), _Safe_initializeProtocolKit = | ||
/** | ||
* Initializes the Safe Core SDK instance. | ||
* @param config - Safe configuration | ||
* @throws "Signer must be connected to a provider" | ||
* @throws "SafeProxy contract is not deployed on the current network" | ||
* @throws "MultiSend contract is not deployed on the current network" | ||
* @throws "MultiSendCallOnly contract is not deployed on the current network" | ||
*/ | ||
async function _Safe_initializeProtocolKit(config) { | ||
const { provider, signer, isL1SafeSingleton, contractNetworks } = config; | ||
__classPrivateFieldSet(this, _Safe_safeProvider, new SafeProvider_1.default({ | ||
provider, | ||
signer | ||
}), "f"); | ||
if ((0, types_2.isSafeConfigWithPredictedSafe)(config)) { | ||
__classPrivateFieldSet(this, _Safe_predictedSafe, config.predictedSafe, "f"); | ||
__classPrivateFieldSet(this, _Safe_contractManager, await contractManager_1.default.init({ | ||
provider, | ||
predictedSafe: __classPrivateFieldGet(this, _Safe_predictedSafe, "f"), | ||
isL1SafeSingleton, | ||
contractNetworks | ||
}, __classPrivateFieldGet(this, _Safe_safeProvider, "f")), "f"); | ||
} | ||
} | ||
_Safe_predictedSafe = new WeakMap(), _Safe_safeProvider = 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(); | ||
else { | ||
__classPrivateFieldSet(this, _Safe_contractManager, await contractManager_1.default.init({ | ||
provider, | ||
safeAddress: config.safeAddress, | ||
isL1SafeSingleton, | ||
contractNetworks | ||
}, __classPrivateFieldGet(this, _Safe_safeProvider, "f")), "f"); | ||
} | ||
__classPrivateFieldSet(this, _Safe_ownerManager, new ownerManager_1.default(__classPrivateFieldGet(this, _Safe_safeProvider, "f"), __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract), "f"); | ||
__classPrivateFieldSet(this, _Safe_moduleManager, new moduleManager_1.default(__classPrivateFieldGet(this, _Safe_safeProvider, "f"), __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract), "f"); | ||
__classPrivateFieldSet(this, _Safe_guardManager, new guardManager_1.default(__classPrivateFieldGet(this, _Safe_safeProvider, "f"), __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract), "f"); | ||
__classPrivateFieldSet(this, _Safe_fallbackHandlerManager, new fallbackHandlerManager_1.default(__classPrivateFieldGet(this, _Safe_safeProvider, "f"), __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract), "f"); | ||
}, _Safe_getFallbackHandlerContract = | ||
/** | ||
* Get the fallback handler contract | ||
* | ||
* @returns The fallback Handler contract | ||
*/ | ||
async function _Safe_getFallbackHandlerContract() { | ||
if (!__classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract) { | ||
throw new Error('Safe is not deployed'); | ||
} | ||
const safeVersion = (await __classPrivateFieldGet(this, _Safe_contractManager, "f").safeContract.getVersion()) ?? config_1.DEFAULT_SAFE_VERSION; | ||
const chainId = await __classPrivateFieldGet(this, _Safe_safeProvider, "f").getChainId(); | ||
const compatibilityFallbackHandlerContract = await (0, safeDeploymentContracts_1.getCompatibilityFallbackHandlerContract)({ | ||
safeProvider: __classPrivateFieldGet(this, _Safe_safeProvider, "f"), | ||
safeVersion, | ||
customContracts: __classPrivateFieldGet(this, _Safe_contractManager, "f").contractNetworks?.[chainId.toString()] | ||
}); | ||
return compatibilityFallbackHandlerContract; | ||
}; | ||
exports.default = Safe; | ||
//# sourceMappingURL=Safe.js.map |
@@ -7,4 +7,3 @@ import Safe from './Safe'; | ||
#private; | ||
static create({ provider, signer, safeVersion, isL1SafeSingleton, contractNetworks }: SafeFactoryConfig): Promise<SafeFactory>; | ||
private init; | ||
static init({ provider, signer, safeVersion, isL1SafeSingleton, contractNetworks }: SafeFactoryConfig): Promise<SafeFactory>; | ||
getSafeProvider(): SafeProvider; | ||
@@ -11,0 +10,0 @@ getSafeVersion(): SafeVersion; |
"use strict"; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
@@ -8,11 +13,6 @@ if (kind === "m") throw new TypeError("Private method is not writable"); | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var _SafeFactory_contractNetworks, _SafeFactory_isL1SafeSingleton, _SafeFactory_safeVersion, _SafeFactory_safeProxyFactoryContract, _SafeFactory_safeContract, _SafeFactory_provider, _SafeFactory_signer, _SafeFactory_safeProvider; | ||
var _SafeFactory_instances, _SafeFactory_contractNetworks, _SafeFactory_isL1SafeSingleton, _SafeFactory_safeVersion, _SafeFactory_safeProxyFactoryContract, _SafeFactory_safeContract, _SafeFactory_provider, _SafeFactory_signer, _SafeFactory_safeProvider, _SafeFactory_initializeSafeFactory; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -26,2 +26,3 @@ const Safe_1 = __importDefault(require("./Safe")); | ||
constructor() { | ||
_SafeFactory_instances.add(this); | ||
_SafeFactory_contractNetworks.set(this, void 0); | ||
@@ -36,5 +37,5 @@ _SafeFactory_isL1SafeSingleton.set(this, void 0); | ||
} | ||
static async create({ provider, signer, safeVersion = config_1.DEFAULT_SAFE_VERSION, isL1SafeSingleton = false, contractNetworks }) { | ||
static async init({ provider, signer, safeVersion = config_1.DEFAULT_SAFE_VERSION, isL1SafeSingleton = false, contractNetworks }) { | ||
const safeFactorySdk = new SafeFactory(); | ||
await safeFactorySdk.init({ | ||
await __classPrivateFieldGet(safeFactorySdk, _SafeFactory_instances, "m", _SafeFactory_initializeSafeFactory).call(safeFactorySdk, { | ||
provider, | ||
@@ -48,23 +49,2 @@ signer, | ||
} | ||
async init({ provider, signer, safeVersion, isL1SafeSingleton, contractNetworks }) { | ||
__classPrivateFieldSet(this, _SafeFactory_provider, provider, "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_signer, signer, "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_safeProvider, new SafeProvider_1.default({ provider, signer }), "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_safeVersion, safeVersion, "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_isL1SafeSingleton, isL1SafeSingleton, "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_contractNetworks, contractNetworks, "f"); | ||
const chainId = await __classPrivateFieldGet(this, _SafeFactory_safeProvider, "f").getChainId(); | ||
const customContracts = contractNetworks?.[chainId.toString()]; | ||
__classPrivateFieldSet(this, _SafeFactory_safeProxyFactoryContract, await (0, safeDeploymentContracts_1.getProxyFactoryContract)({ | ||
safeProvider: __classPrivateFieldGet(this, _SafeFactory_safeProvider, "f"), | ||
safeVersion, | ||
customContracts | ||
}), "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_safeContract, await (0, safeDeploymentContracts_1.getSafeContract)({ | ||
safeProvider: __classPrivateFieldGet(this, _SafeFactory_safeProvider, "f"), | ||
safeVersion, | ||
isL1SafeSingleton, | ||
customContracts | ||
}), "f"); | ||
} | ||
getSafeProvider() { | ||
@@ -128,3 +108,3 @@ return __classPrivateFieldGet(this, _SafeFactory_safeProvider, "f"); | ||
} | ||
const safe = await Safe_1.default.create({ | ||
const safe = await Safe_1.default.init({ | ||
provider: __classPrivateFieldGet(this, _SafeFactory_provider, "f"), | ||
@@ -139,4 +119,24 @@ signer: __classPrivateFieldGet(this, _SafeFactory_signer, "f"), | ||
} | ||
_SafeFactory_contractNetworks = new WeakMap(), _SafeFactory_isL1SafeSingleton = new WeakMap(), _SafeFactory_safeVersion = new WeakMap(), _SafeFactory_safeProxyFactoryContract = new WeakMap(), _SafeFactory_safeContract = new WeakMap(), _SafeFactory_provider = new WeakMap(), _SafeFactory_signer = new WeakMap(), _SafeFactory_safeProvider = new WeakMap(); | ||
_SafeFactory_contractNetworks = new WeakMap(), _SafeFactory_isL1SafeSingleton = new WeakMap(), _SafeFactory_safeVersion = new WeakMap(), _SafeFactory_safeProxyFactoryContract = new WeakMap(), _SafeFactory_safeContract = new WeakMap(), _SafeFactory_provider = new WeakMap(), _SafeFactory_signer = new WeakMap(), _SafeFactory_safeProvider = new WeakMap(), _SafeFactory_instances = new WeakSet(), _SafeFactory_initializeSafeFactory = async function _SafeFactory_initializeSafeFactory({ provider, signer, safeVersion, isL1SafeSingleton, contractNetworks }) { | ||
__classPrivateFieldSet(this, _SafeFactory_provider, provider, "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_signer, signer, "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_safeProvider, new SafeProvider_1.default({ provider, signer }), "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_safeVersion, safeVersion, "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_isL1SafeSingleton, isL1SafeSingleton, "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_contractNetworks, contractNetworks, "f"); | ||
const chainId = await __classPrivateFieldGet(this, _SafeFactory_safeProvider, "f").getChainId(); | ||
const customContracts = contractNetworks?.[chainId.toString()]; | ||
__classPrivateFieldSet(this, _SafeFactory_safeProxyFactoryContract, await (0, safeDeploymentContracts_1.getProxyFactoryContract)({ | ||
safeProvider: __classPrivateFieldGet(this, _SafeFactory_safeProvider, "f"), | ||
safeVersion, | ||
customContracts | ||
}), "f"); | ||
__classPrivateFieldSet(this, _SafeFactory_safeContract, await (0, safeDeploymentContracts_1.getSafeContract)({ | ||
safeProvider: __classPrivateFieldGet(this, _SafeFactory_safeProvider, "f"), | ||
safeVersion, | ||
isL1SafeSingleton, | ||
customContracts | ||
}), "f"); | ||
}; | ||
exports.default = SafeFactory; | ||
//# sourceMappingURL=SafeFactory.js.map |
@@ -18,2 +18,3 @@ "use strict"; | ||
const utils_2 = require("./contracts/utils"); | ||
const constants_1 = require("./utils/constants"); | ||
const contractInstances_1 = require("./contracts/contractInstances"); | ||
@@ -98,3 +99,3 @@ class SafeProvider { | ||
const contractCode = await __classPrivateFieldGet(this, _SafeProvider_externalProvider, "f").getCode(address, blockTag); | ||
return contractCode !== '0x'; | ||
return contractCode !== constants_1.EMPTY_DATA; | ||
} | ||
@@ -101,0 +102,0 @@ async getStorageAt(address, position) { |
@@ -74,2 +74,3 @@ "use strict"; | ||
{ chainId: 686n, shortName: 'kar' }, | ||
{ chainId: 690n, shortName: 'redstone' }, | ||
{ chainId: 787n, shortName: 'aca' }, | ||
@@ -87,2 +88,3 @@ { chainId: 919n, shortName: 'modesep' }, | ||
{ chainId: 1116n, shortName: 'core' }, | ||
{ chainId: 1135n, shortName: 'lisk' }, | ||
{ chainId: 1230n, shortName: 'UltronTestnet' }, | ||
@@ -114,2 +116,3 @@ { chainId: 1231n, shortName: 'UltronMainnet' }, | ||
{ chainId: 2358n, shortName: 'kroma-sepolia' }, | ||
{ chainId: 2810n, shortName: 'hmorph' }, | ||
{ chainId: 3636n, shortName: 'BTNX' }, | ||
@@ -119,2 +122,3 @@ { chainId: 3737n, shortName: 'csb' }, | ||
{ chainId: 4002n, shortName: 'tftm' }, | ||
{ chainId: 4078n, shortName: 'muster' }, | ||
{ chainId: 4157n, shortName: 'crossfi-testnet' }, | ||
@@ -165,2 +169,3 @@ { chainId: 4202n, shortName: 'lisksep' }, | ||
{ chainId: 17000n, shortName: 'holesky' }, | ||
{ chainId: 17069n, shortName: 'garnet' }, | ||
{ chainId: 17172n, shortName: 'eclipse' }, | ||
@@ -211,4 +216,6 @@ { chainId: 18231n, shortName: 'unreal' }, | ||
{ chainId: 534353n, shortName: 'scr-alpha' }, | ||
{ chainId: 555666n, shortName: 'eclipset' }, | ||
{ chainId: 622277n, shortName: 'rth' }, | ||
{ chainId: 713715n, shortName: 'sei-devnet' }, | ||
{ chainId: 7225878n, shortName: 'saakuru' }, | ||
{ chainId: 7777777n, shortName: 'zora' }, | ||
@@ -215,0 +222,0 @@ { chainId: 6038361n, shortName: 'azkyt' }, |
MIT License | ||
Copyright (c) 2021-2023 Safe Ecosystem Foundation | ||
Copyright (c) 2021-2024 Safe Ecosystem Foundation | ||
@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
{ | ||
"name": "@safe-global/protocol-kit", | ||
"version": "4.0.0-alpha.0", | ||
"version": "4.0.0", | ||
"description": "SDK to interact with Safe smart contracts", | ||
@@ -54,19 +54,18 @@ "main": "dist/src/index.js", | ||
"@safe-global/safe-contracts-v1.4.1": "npm:@safe-global/safe-contracts@1.4.1", | ||
"@safe-global/safe-core-sdk-types": "^5.0.0-alpha.0", | ||
"@types/chai": "^4.3.11", | ||
"@safe-global/safe-core-sdk-types": "^5.0.0", | ||
"@types/chai": "^4.3.16", | ||
"@types/chai-as-promised": "^7.1.8", | ||
"@types/mocha": "^10.0.6", | ||
"@types/semver": "^7.5.6", | ||
"@types/web3": "1.0.20", | ||
"@types/semver": "^7.5.8", | ||
"@types/yargs": "^17.0.32", | ||
"chai": "^4.3.10", | ||
"chai-as-promised": "^7.1.1", | ||
"dotenv": "^16.3.1", | ||
"dotenv": "^16.4.5", | ||
"hardhat": "^2.19.3", | ||
"hardhat-deploy": "^0.11.45", | ||
"hardhat-deploy-ethers": "^0.4.1", | ||
"hardhat-deploy-ethers": "^0.4.2", | ||
"mocha": "^10.2.0", | ||
"nyc": "^15.1.0", | ||
"tsconfig-paths": "^4.2.0", | ||
"viem": "^2.9.19", | ||
"viem": "^2.10.2", | ||
"web3": "^4.7.0", | ||
@@ -77,8 +76,8 @@ "yargs": "^17.7.2" | ||
"@noble/hashes": "^1.3.3", | ||
"@safe-global/safe-deployments": "^1.35.0", | ||
"@safe-global/safe-deployments": "^1.36.0", | ||
"abitype": "^1.0.2", | ||
"ethereumjs-util": "^7.1.5", | ||
"ethers": "^6.7.1", | ||
"semver": "^7.5.4" | ||
"ethers": "^6.12.1", | ||
"semver": "^7.6.1" | ||
} | ||
} |
1017
README.md
@@ -7,17 +7,19 @@ # Protocol Kit | ||
Software development kit that facilitates the interaction with the [Safe contracts](https://github.com/safe-global/safe-contracts). | ||
Software development kit that facilitates the interaction with [Safe Smart Accounts](https://github.com/safe-global/safe-smart-account). | ||
## Table of contents | ||
- [Documentation](#documentation) | ||
- [Installation](#installation) | ||
- [Build](#build) | ||
- [Tests](#tests) | ||
- [Getting Started](#getting-started) | ||
- [Safe Factory API Reference](#factory-api) | ||
- [Safe Core SDK API Reference](#sdk-api) | ||
- [Quick Start](#quick-start) | ||
- [Need Help or Have Questions?](#need-help-or-have-questions) | ||
- [Contributing](#contributing) | ||
- [License](#license) | ||
- [Contributors](#contributors) | ||
## <a name="installation">Installation</a> | ||
## Documentation | ||
Head to the [Protocol Kit docs](https://docs.safe.global/sdk/protocol-kit) to learn more about how to use this SDK. | ||
## Installation | ||
Install the package with yarn or npm: | ||
@@ -30,283 +32,22 @@ | ||
## <a name="build">Build</a> | ||
## Quick Start | ||
Build the package with yarn or npm: | ||
- `provider`: You can set an EIP-1193 compatible provider or an HTTP/WebSocket RPC URL. | ||
- `signer`: This is an optional parameter. It should be the provider's address you want to use or a private key. If not set, it will try to fetch a connected account from the provider. | ||
```bash | ||
yarn build | ||
npm run build | ||
``` | ||
Loading an already deployed Safe, using the `safeAddress` property: | ||
## <a name="tests">Tests</a> | ||
Create a `.env` file with environment variables. You can use the `.env.example` file as a reference. | ||
Test the package with yarn or npm: | ||
```bash | ||
yarn test | ||
npm run test | ||
``` | ||
## <a name="getting-started">Getting Started</a> | ||
The following steps show how to set up the Protocol Kit, deploy a new Safe, create a Safe transaction, generate the required signatures from owners and execute the transaction. However, using the Protocol Kit alone will not allow for the collection of owner signatures off-chain. To do this and be able to see and confirm the pending transactions shown in the [Safe Web App](https://app.safe.global/), it is recommended that you follow this other [guide](/guides/integrating-the-safe-core-sdk.md) that covers the use of the Protocol Kit, combined with the API Kit. | ||
### 1. Instantiate an EthAdapter | ||
First of all, we need to create an `EthAdapter`, which contains all the required utilities for the SDKs to interact with the blockchain. It acts as a wrapper for [web3.js](https://web3js.readthedocs.io/) or [ethers.js](https://docs.ethers.org/v6/) Ethereum libraries. | ||
Depending on the library used by the Dapp, there are two options: | ||
- [Create an `EthersAdapter` instance](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit/src/adapters/ethers) | ||
- [Create a `Web3Adapter` instance](https://github.com/safe-global/safe-core-sdk/tree/main/packages/protocol-kit/src/adapters/web3) | ||
Once the instance of `EthersAdapter` or `Web3Adapter` is created, it can be used in the SDK initialization. | ||
### 2. Deploy a new Safe | ||
To deploy a new Safe account instantiate the `SafeFactory` class and call the `deploySafe` method with the right params to configure the new Safe. This includes defining the list of owners and the threshold of the Safe. A Safe account with three owners and threshold equal three will be used as the starting point for this example but any Safe configuration is valid. | ||
```js | ||
import Safe, { SafeFactory, SafeAccountConfig } from '@safe-global/protocol-kit' | ||
const safeFactory = await SafeFactory.create({ ethAdapter }) | ||
const owners = ['0x<address>', '0x<address>', '0x<address>'] | ||
const threshold = 3 | ||
const safeAccountConfig: SafeAccountConfig = { | ||
owners, | ||
threshold | ||
// ... | ||
} | ||
const safeSdk: Safe = await safeFactory.deploySafe({ safeAccountConfig }) | ||
``` | ||
The `deploySafe` method executes a transaction from the `owner1` account, deploys a new Safe and returns an instance of the Protocol Kit connected to the new Safe. Check the `deploySafe` method in the [API Reference](#factory-api) for more details on additional configuration parameters and callbacks. | ||
Call the `getAddress` method, for example, to check the address of the newly deployed Safe. | ||
```js | ||
const newSafeAddress = await safeSdk.getAddress() | ||
``` | ||
To instantiate the Protocol Kit from an existing Safe just pass to it an instance of the `EthAdapter` class and the Safe address. | ||
```js | ||
import Safe from '@safe-global/protocol-kit' | ||
const safeSdk: Safe = await Safe.create({ ethAdapter: ethAdapterOwner1, safeAddress }) | ||
const protocolKit = await Safe.init({ | ||
provider, | ||
signer, | ||
safeAddress | ||
}) | ||
``` | ||
Check the `create` method in the [API Reference](#sdk-api) for more details on additional configuration parameters. | ||
Initialization of an undeployed Safe using the `predictedSafe` property. Because Safes are deployed in a deterministic way, passing a `predictedSafe` will allow to initialize the SDK with the Safe configuration and use it to some extent before it's deployed: | ||
### 3. Create a Safe transaction | ||
```js | ||
import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' | ||
const safeTransactionData: MetaTransactionData = { | ||
to: '0x<address>', | ||
value: '<eth_value_in_wei>', | ||
data: '0x<data>' | ||
} | ||
const safeTransaction = await safeSdk.createTransaction({ transactions: [safeTransactionData] }) | ||
``` | ||
Check the `createTransaction` method in the [API Reference](#sdk-api) for additional details on creating MultiSend transactions. | ||
Before executing this transaction, it must be signed by the owners and this can be done off-chain or on-chain. In this example `owner1` will sign it off-chain, `owner2` will sign it on-chain and `owner3` will execute it (the executor also signs the transaction transparently). | ||
### 3.a. Off-chain signatures | ||
The `owner1` account signs the transaction off-chain. | ||
```js | ||
const signedSafeTransaction = await safeSdk.signTransaction(safeTransaction) | ||
``` | ||
Because the signature is off-chain, there is no interaction with the contract and the signature becomes available at `signedSafeTransaction.signatures`. | ||
### 3.b. On-chain signatures | ||
To connect `owner2` to the Safe we need to create a new instance of the class `EthAdapter` passing to its constructor the owner we would like to connect. After `owner2` account is connected to the SDK as a signer the transaction hash will be approved on-chain. | ||
```js | ||
const ethAdapterOwner2 = new EthersAdapter({ ethers, signerOrProvider: owner2 }) | ||
const safeSdk2 = await safeSdk.connect({ ethAdapter: ethAdapterOwner2, safeAddress }) | ||
const txHash = await safeSdk2.getTransactionHash(safeTransaction) | ||
const approveTxResponse = await safeSdk2.approveTransactionHash(txHash) | ||
await approveTxResponse.transactionResponse?.wait() | ||
``` | ||
### 4. Transaction execution | ||
Lastly, `owner3` account is connected to the SDK as a signer and executor of the Safe transaction to execute it. | ||
```js | ||
const ethAdapterOwner3 = new EthersAdapter({ ethers, signerOrProvider: owner3 }) | ||
const safeSdk3 = await safeSdk2.connect({ ethAdapter: ethAdapterOwner3, safeAddress }) | ||
const executeTxResponse = await safeSdk3.executeTransaction(safeTransaction) | ||
await executeTxResponse.transactionResponse?.wait() | ||
``` | ||
All the signatures used to execute the transaction are now available at `safeTransaction.signatures`. | ||
## <a name="factory-api">Safe Factory API Reference</a> | ||
### create | ||
Returns an instance of the Safe Factory. | ||
```js | ||
import { SafeFactory } from '@safe-global/protocol-kit' | ||
const safeFactory = await SafeFactory.create({ ethAdapter }) | ||
``` | ||
- The `isL1SafeSingleton` flag | ||
There are two versions of the Safe contracts: [Safe.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/Safe.sol) that does not trigger events in order to save gas and [SafeL2.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/SafeL2.sol) that does, which is more appropriate for L2 networks. | ||
By default `Safe.sol` will be only used on Ethereum Mainnet. For the rest of the networks where the Safe contracts are already deployed, the `SafeL2.sol` contract will be used unless you add the `isL1SafeSingleton` flag to force the use of the `Safe.sol` contract. | ||
```js | ||
const safeFactory = await SafeFactory.create({ ethAdapter, isL1SafeSingleton: true }) | ||
``` | ||
- The `contractNetworks` property | ||
If the Safe contracts are not deployed to your current network, the `contractNetworks` property will be required to point to the addresses of the Safe contracts previously deployed by you. | ||
```js | ||
import { ContractNetworksConfig } from '@safe-global/protocol-kit' | ||
const chainId = await ethAdapter.getChainId() | ||
const contractNetworks: ContractNetworksConfig = { | ||
[chainId]: { | ||
safeSingletonAddress: '<SINGLETON_ADDRESS>', | ||
safeProxyFactoryAddress: '<PROXY_FACTORY_ADDRESS>', | ||
multiSendAddress: '<MULTI_SEND_ADDRESS>', | ||
multiSendCallOnlyAddress: '<MULTI_SEND_CALL_ONLY_ADDRESS>', | ||
fallbackHandlerAddress: '<FALLBACK_HANDLER_ADDRESS>', | ||
signMessageLibAddress: '<SIGN_MESSAGE_LIB_ADDRESS>', | ||
createCallAddress: '<CREATE_CALL_ADDRESS>', | ||
simulateTxAccessorAddress: '<SIMULATE_TX_ACCESSOR_ADDRESS>', | ||
safeSingletonAbi: '<SINGLETON_ABI>', // Optional. Only needed with web3.js | ||
safeProxyFactoryAbi: '<PROXY_FACTORY_ABI>', // Optional. Only needed with web3.js | ||
multiSendAbi: '<MULTI_SEND_ABI>', // Optional. Only needed with web3.js | ||
multiSendCallOnlyAbi: '<MULTI_SEND_CALL_ONLY_ABI>', // Optional. Only needed with web3.js | ||
fallbackHandlerAbi: '<FALLBACK_HANDLER_ABI>', // Optional. Only needed with web3.js | ||
signMessageLibAbi: '<SIGN_MESSAGE_LIB_ABI>', // Optional. Only needed with web3.js | ||
createCallAbi: '<CREATE_CALL_ABI>', // Optional. Only needed with web3.js | ||
simulateTxAccessorAbi: '<SIMULATE_TX_ACCESSOR_ABI>' // Optional. Only needed with web3.js | ||
} | ||
} | ||
const safeFactory = await SafeFactory.create({ ethAdapter, contractNetworks }) | ||
``` | ||
- The `safeVersion` property | ||
The `SafeFactory` constructor also accepts the `safeVersion` property to specify the Safe contract version that will be deployed. This string can take the values `1.0.0`, `1.1.1`, `1.2.0`, `1.3.0` or `1.4.1`. If not specified, the `DEFAULT_SAFE_VERSION` value will be used. | ||
```js | ||
const safeVersion = 'X.Y.Z' | ||
const safeFactory = await SafeFactory.create({ ethAdapter, safeVersion }) | ||
``` | ||
### deploySafe | ||
Deploys a new Safe and returns an instance of the Protocol Kit connected to the deployed Safe. The Singleton address, contract version and layer instance (`Safe.sol` or `SafeL2.sol`) of the deployed Safe will depend on the configuration used to create the `safeFactory`. | ||
```js | ||
const safeAccountConfig: SafeAccountConfig = { | ||
owners, | ||
threshold, | ||
to, // Optional | ||
data, // Optional | ||
fallbackHandler, // Optional | ||
paymentToken, // Optional | ||
payment, // Optional | ||
paymentReceiver // Optional | ||
} | ||
const safeSdk = await safeFactory.deploySafe({ safeAccountConfig }) | ||
``` | ||
This method can optionally receive the `saltNonce` parameter. | ||
```js | ||
const safeAccountConfig: SafeAccountConfig = { | ||
owners, | ||
threshold, | ||
to, // Optional | ||
data, // Optional | ||
fallbackHandler, // Optional | ||
paymentToken, // Optional | ||
payment, // Optional | ||
paymentReceiver // Optional | ||
} | ||
const saltNonce = '<YOUR_CUSTOM_VALUE>' | ||
const safeSdk = await safeFactory.deploySafe({ safeAccountConfig, saltNonce }) | ||
``` | ||
Optionally, some properties can be passed as execution options: | ||
```js | ||
const options: Web3TransactionOptions = { | ||
from, // Optional | ||
gas, // Optional | ||
gasPrice, // Optional | ||
maxFeePerGas, // Optional | ||
maxPriorityFeePerGas // Optional | ||
nonce // Optional | ||
} | ||
``` | ||
```js | ||
const options: EthersTransactionOptions = { | ||
from, // Optional | ||
gasLimit, // Optional | ||
gasPrice, // Optional | ||
maxFeePerGas, // Optional | ||
maxPriorityFeePerGas // Optional | ||
nonce // Optional | ||
} | ||
``` | ||
```js | ||
const safeSdk = await safeFactory.deploySafe({ safeAccountConfig, safeDeploymentConfig, options }) | ||
``` | ||
It can also take an optional callback which receives the `txHash` of the Safe deployment transaction prior to returning a new instance of the Protocol Kit: | ||
```js | ||
const callback = (txHash: string): void => { | ||
console.log({ txHash }) | ||
} | ||
const safeSdk = await safeFactory.deploySafe({ safeAccountConfig, callback }) | ||
``` | ||
## <a name="sdk-api">Safe Core SDK API Reference</a> | ||
### create | ||
Returns an instance of the Protocol Kit connected to a Safe. The provided Safe must be a `safeAddress` or a `predictedSafe`. | ||
Initialization of a deployed Safe using the `safeAddress` property: | ||
```js | ||
import Safe from '@safe-global/protocol-kit' | ||
const safeSdk = await Safe.create({ ethAdapter, safeAddress }) | ||
``` | ||
Initialization of a not deployed Safe using the `predictedSafe` property. Because Safes are deployed in a deterministic way, passing a `predictedSafe` will allow to initialize the SDK with the Safe configuration and use it to some extent before it is deployed: | ||
```js | ||
import Safe, { PredictedSafeProps } from '@safe-global/protocol-kit' | ||
@@ -319,717 +60,19 @@ | ||
const safeSdk = await Safe.create({ ethAdapter, predictedSafe }) | ||
``` | ||
- The `isL1SafeSingleton` flag | ||
There are two versions of the Safe contracts: [Safe.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/Safe.sol) that does not trigger events in order to save gas and [SafeL2.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/SafeL2.sol) that does, which is more appropriate for L2 networks. | ||
By default `Safe.sol` will be only used on Ethereum Mainnet. For the rest of the networks where the Safe contracts are already deployed, the `SafeL2.sol` contract will be used unless you add the `isL1SafeSingleton` flag to force the use of the `Safe.sol` contract. | ||
```js | ||
const safeSdk = await Safe.create({ ethAdapter, safeAddress, isL1SafeSingleton: true }) | ||
``` | ||
- The `contractNetworks` property | ||
If the Safe contracts are not deployed to your current network, the `contractNetworks` property will be required to point to the addresses of the Safe contracts previously deployed by you. | ||
```js | ||
import { ContractNetworksConfig } from '@safe-global/protocol-kit' | ||
const chainId = await ethAdapter.getChainId() | ||
const contractNetworks: ContractNetworksConfig = { | ||
[chainId]: { | ||
safeSingletonAddress: '<SINGLETON_ADDRESS>', | ||
safeProxyFactoryAddress: '<PROXY_FACTORY_ADDRESS>', | ||
multiSendAddress: '<MULTI_SEND_ADDRESS>', | ||
multiSendCallOnlyAddress: '<MULTI_SEND_CALL_ONLY_ADDRESS>', | ||
fallbackHandlerAddress: '<FALLBACK_HANDLER_ADDRESS>', | ||
signMessageLibAddress: '<SIGN_MESSAGE_LIB_ADDRESS>', | ||
createCallAddress: '<CREATE_CALL_ADDRESS>', | ||
simulateTxAccessorAddress: '<SIMULATE_TX_ACCESSOR_ADDRESS>', | ||
safeSingletonAbi: '<SINGLETON_ABI>', // Optional. Only needed with web3.js | ||
safeProxyFactoryAbi: '<PROXY_FACTORY_ABI>', // Optional. Only needed with web3.js | ||
multiSendAbi: '<MULTI_SEND_ABI>', // Optional. Only needed with web3.js | ||
multiSendCallOnlyAbi: '<MULTI_SEND_CALL_ONLY_ABI>', // Optional. Only needed with web3.js | ||
fallbackHandlerAbi: '<FALLBACK_HANDLER_ABI>', // Optional. Only needed with web3.js | ||
signMessageLibAbi: '<SIGN_MESSAGE_LIB_ABI>', // Optional. Only needed with web3.js | ||
createCallAbi: '<CREATE_CALL_ABI>', // Optional. Only needed with web3.js | ||
simulateTxAccessorAbi: '<SIMULATE_TX_ACCESSOR_ABI>' // Optional. Only needed with web3.js | ||
} | ||
} | ||
const safeSdk = await Safe.create({ ethAdapter, safeAddress, contractNetworks }) | ||
``` | ||
### connect | ||
Returns a new instance of the Protocol Kit connected to a new Safe or a new Signer. The new connected signer can be passed via the `ethAdapter` property while the new connected Safe can be passed using a `safeAddress` or a `predictedSafe`. | ||
Connection of a deployed Safe using the `safeAddress` property: | ||
```js | ||
const safeSdk = await safeSdk.connect({ ethAdapter, safeAddress }) | ||
``` | ||
Connection of a not deployed Safe using the `predictedSafe` property. Because Safes are deployed in a deterministic way, passing a `predictedSafe` will allow to connect a Safe to the SDK with the Safe configuration: | ||
```js | ||
import { PredictedSafeProps } from '@safe-global/protocol-kit' | ||
const predictedSafe: PredictedSafeProps = { | ||
safeAccountConfig, | ||
safeDeploymentConfig | ||
} | ||
const safeSdk = await safeSdk.connect({ ethAdapter, predictedSafe }) | ||
``` | ||
- The `isL1SafeSingleton` flag | ||
There are two versions of the Safe contracts: [Safe.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/Safe.sol) that does not trigger events in order to save gas and [SafeL2.sol](https://github.com/safe-global/safe-contracts/blob/v1.4.1/contracts/SafeL2.sol) that does, which is more appropriate for L2 networks. | ||
By default `Safe.sol` will be only used on Ethereum Mainnet. For the rest of the networks where the Safe contracts are already deployed, the `SafeL2.sol` contract will be used unless you add the `isL1SafeSingleton` flag to force the use of the `Safe.sol` contract. | ||
```js | ||
const safeSdk = await Safe.connect({ ethAdapter, safeAddress, isL1SafeSingleton: true }) | ||
``` | ||
- The `contractNetworks` property | ||
If the Safe contracts are not deployed to your current network, the `contractNetworks` property will be required to point to the addresses of the Safe contracts previously deployed by you. | ||
```js | ||
import { ContractNetworksConfig } from '@safe-global/protocol-kit' | ||
const chainId = await ethAdapter.getChainId() | ||
const contractNetworks: ContractNetworksConfig = { | ||
[chainId]: { | ||
safeSingletonAddress: '<SINGLETON_ADDRESS>', | ||
safeProxyFactoryAddress: '<PROXY_FACTORY_ADDRESS>', | ||
multiSendAddress: '<MULTI_SEND_ADDRESS>', | ||
multiSendCallOnlyAddress: '<MULTI_SEND_CALL_ONLY_ADDRESS>', | ||
fallbackHandlerAddress: '<FALLBACK_HANDLER_ADDRESS>', | ||
signMessageLibAddress: '<SIGN_MESSAGE_LIB_ADDRESS>', | ||
createCallAddress: '<CREATE_CALL_ADDRESS>', | ||
simulateTxAccessorAddress: '<SIMULATE_TX_ACCESSOR_ADDRESS>', | ||
safeSingletonAbi: '<SINGLETON_ABI>', // Optional. Only needed with web3.js | ||
safeProxyFactoryAbi: '<PROXY_FACTORY_ABI>', // Optional. Only needed with web3.js | ||
multiSendAbi: '<MULTI_SEND_ABI>', // Optional. Only needed with web3.js | ||
multiSendCallOnlyAbi: '<MULTI_SEND_CALL_ONLY_ABI>', // Optional. Only needed with web3.js | ||
fallbackHandlerAbi: '<FALLBACK_HANDLER_ABI>', // Optional. Only needed with web3.js | ||
signMessageLibAbi: '<SIGN_MESSAGE_LIB_ABI>', // Optional. Only needed with web3.js | ||
createCallAbi: '<CREATE_CALL_ABI>', // Optional. Only needed with web3.js | ||
simulateTxAccessorAbi: '<SIMULATE_TX_ACCESSOR_ABI>' // Optional. Only needed with web3.js | ||
} | ||
} | ||
const safeSdk = await Safe.connect({ ethAdapter, safeAddress, contractNetworks }) | ||
``` | ||
### getAddress | ||
Returns the address of the current SafeProxy contract. | ||
```js | ||
const safeAddress = await safeSdk.getAddress() | ||
``` | ||
### getContractVersion | ||
Returns the Safe Singleton contract version. | ||
```js | ||
const contractVersion = await safeSdk.getContractVersion() | ||
``` | ||
### getOwners | ||
Returns the list of Safe owner accounts. | ||
```js | ||
const ownerAddresses = await safeSdk.getOwners() | ||
``` | ||
### getNonce | ||
Returns the Safe nonce. | ||
```js | ||
const nonce = await safeSdk.getNonce() | ||
``` | ||
### getThreshold | ||
Returns the Safe threshold. | ||
```js | ||
const threshold = await safeSdk.getThreshold() | ||
``` | ||
### getChainId | ||
Returns the chainId of the connected network. | ||
```js | ||
const chainId = await safeSdk.getChainId() | ||
``` | ||
### getBalance | ||
Returns the ETH balance of the Safe. | ||
```js | ||
const balance = await safeSdk.getBalance() | ||
``` | ||
### getGuard | ||
Returns the enabled Safe guard or 0x address if no guards are enabled. | ||
```js | ||
const guardAddress = await safeSdk.getGuard() | ||
``` | ||
### getModules | ||
Returns the list of addresses of all the enabled Safe modules. | ||
```js | ||
const moduleAddresses = await safeSdk.getModules() | ||
``` | ||
### isModuleEnabled | ||
Checks if a specific Safe module is enabled for the current Safe. | ||
```js | ||
const isEnabled = await safeSdk.isModuleEnabled(moduleAddress) | ||
``` | ||
### isOwner | ||
Checks if a specific address is an owner of the current Safe. | ||
```js | ||
const isOwner = await safeSdk.isOwner(address) | ||
``` | ||
### createTransaction | ||
Returns a Safe transaction ready to be signed by the owners and executed. The Protocol Kit supports the creation of single Safe transactions but also MultiSend transactions. | ||
This method takes an array of `MetaTransactionData` objects that represent the individual transactions we want to include in our MultiSend transaction. | ||
When the array contains only one transaction, it is not wrapped in the MultiSend. | ||
```js | ||
const transactions: MetaTransactionData[] = [ | ||
{ | ||
to, | ||
data, | ||
value, | ||
operation // Optional | ||
}, | ||
{ | ||
to, | ||
data, | ||
value, | ||
operation // Optional | ||
} | ||
// ... | ||
] | ||
const safeTransaction = await safeSdk.createTransaction({ transactions }) | ||
``` | ||
This method can also receive the `options` parameter to set the optional properties in the MultiSend transaction: | ||
```js | ||
const transactions: MetaTransactionData[] = [ | ||
{ | ||
to, | ||
data, | ||
value, | ||
operation // Optional | ||
}, | ||
{ | ||
to, | ||
data, | ||
value, | ||
operation // Optional | ||
} | ||
// ... | ||
] | ||
const options: SafeTransactionOptionalProps = { | ||
safeTxGas, // Optional | ||
baseGas, // Optional | ||
gasPrice, // Optional | ||
gasToken, // Optional | ||
refundReceiver, // Optional | ||
nonce // Optional | ||
} | ||
const safeTransaction = await safeSdk.createTransaction({ transactions, options }) | ||
``` | ||
In addition, the optional `onlyCalls` parameter, which is `false` by default, allows to force the use of the `MultiSendCallOnly` instead of the `MultiSend` contract when sending a batch transaction: | ||
```js | ||
const onlyCalls = true | ||
const safeTransaction = await safeSdk.createTransaction({ | ||
transactions, | ||
options, | ||
onlyCalls | ||
const protocolKit = await Safe.init({ | ||
provider, | ||
signer, | ||
predictedSafe | ||
}) | ||
``` | ||
If the optional properties are not manually set, the Safe transaction returned will have the default value for each one: | ||
## Need Help or Have Questions? | ||
- `operation`: `OperationType.Call` (0) is the default value. | ||
- `safeTxGas`: The right gas estimation is the default value. | ||
- `baseGas`: 0 is the default value. | ||
- `gasPrice`: 0 is the default value. | ||
- `gasToken`: 0x address is the default value. | ||
- `refundReceiver`: 0x address is the default value. | ||
- `nonce`: The current Safe nonce is the default value. | ||
If you have any doubts, questions, or need assistance, feel free to reach out! [Here you will find how to get support.](https://github.com/safe-global/safe-core-sdk/tree/main/SUPPORT.md) | ||
Read more about [create transactions from a Safe](https://docs.safe.global/safe-core-aa-sdk/protocol-kit#making-a-transaction-from-a-safe). | ||
## Contributing | ||
### createRejectionTransaction | ||
Please read our [contribution guidelines](https://github.com/safe-global/safe-core-sdk/tree/main/CONTRIBUTING.md) before submitting any changes. We appreciate your help! 🙌 | ||
Returns a Safe transaction ready to be signed by the owners that invalidates the pending Safe transaction/s with a specific nonce. | ||
## License | ||
```js | ||
const transactions: MetaTransactionData[] = [ | ||
{ | ||
// ... | ||
} | ||
] | ||
const safeTransaction = await safeSdk.createTransaction({ transactions }) | ||
const rejectionTransaction = await safeSdk.createRejectionTransaction(safeTransaction.data.nonce) | ||
``` | ||
### copyTransaction | ||
Copies a Safe transaction. | ||
```js | ||
const safeTransaction1 = await safeSdk.createTransaction({ transactions }) | ||
const safeTransaction2 = await copyTransaction(safeTransaction1) | ||
``` | ||
### getTransactionHash | ||
Returns the transaction hash of a Safe transaction. | ||
```js | ||
const transactions: MetaTransactionData[] = [ | ||
{ | ||
// ... | ||
} | ||
] | ||
const safeTransaction = await safeSdk.createTransaction({ transactions }) | ||
const txHash = await safeSdk.getTransactionHash(safeTransaction) | ||
``` | ||
### signHash | ||
Signs a hash using the current owner account. | ||
```js | ||
const transactions: MetaTransactionData[] = [ | ||
{ | ||
// ... | ||
} | ||
] | ||
const safeTransaction = await safeSdk.createTransaction({ transactions }) | ||
const txHash = await safeSdk.getTransactionHash(safeTransaction) | ||
const signature = await safeSdk.signHash(txHash) | ||
``` | ||
### signTypedData | ||
Signs a transaction according to the EIP-712 using the current signer account. | ||
```js | ||
const transactions: MetaTransactionData[] = [ | ||
{ | ||
// ... | ||
} | ||
] | ||
const safeTransaction = await safeSdk.createTransaction({ transactions }) | ||
const signature = await safeSdk.signTypedData(safeTransaction) | ||
``` | ||
### signTransaction | ||
Returns a new `SafeTransaction` object that includes the signature of the current owner. `eth_sign` will be used by default to generate the signature. | ||
```js | ||
const transactions: MetaTransactionData[] = [ | ||
{ | ||
// ... | ||
} | ||
] | ||
const safeTransaction = await safeSdk.createTransaction({ transactions }) | ||
const signedSafeTransaction = await safeSdk.signTransaction(safeTransaction) | ||
``` | ||
Optionally, an additional parameter can be passed to specify a different way of signing: | ||
```js | ||
const signedSafeTransaction = await safeSdk.signTransaction( | ||
safeTransaction, | ||
SigningMethod.ETH_SIGN_TYPED_DATA | ||
) | ||
``` | ||
```js | ||
const signedSafeTransaction = await safeSdk.signTransaction(safeTransaction, SigningMethod.ETH_SIGN) // default option. | ||
``` | ||
### approveTransactionHash | ||
Approves a hash on-chain using the current owner account. | ||
```js | ||
const transactions: MetaTransactionData[] = [ | ||
{ | ||
// ... | ||
} | ||
] | ||
const safeTransaction = await safeSdk.createTransaction({ transactions }) | ||
const txHash = await safeSdk.getTransactionHash(safeTransaction) | ||
const txResponse = await safeSdk.approveTransactionHash(txHash) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
Optionally, some properties can be passed as execution options: | ||
```js | ||
const options: Web3TransactionOptions = { | ||
from, // Optional | ||
gas, // Optional | ||
gasPrice, // Optional | ||
maxFeePerGas, // Optional | ||
maxPriorityFeePerGas // Optional | ||
nonce // Optional | ||
} | ||
``` | ||
```js | ||
const options: EthersTransactionOptions = { | ||
from, // Optional | ||
gasLimit, // Optional | ||
gasPrice, // Optional | ||
maxFeePerGas, // Optional | ||
maxPriorityFeePerGas // Optional | ||
nonce // Optional | ||
} | ||
``` | ||
```js | ||
const txResponse = await safeSdk.approveTransactionHash(txHash, options) | ||
``` | ||
### getOwnersWhoApprovedTx | ||
Returns a list of owners who have approved a specific Safe transaction. | ||
```js | ||
const transactions: MetaTransactionData[] = [ | ||
{ | ||
// ... | ||
} | ||
] | ||
const safeTransaction = await safeSdk.createTransaction({ transactions }) | ||
const txHash = await safeSdk.getTransactionHash(safeTransaction) | ||
const ownerAddresses = await safeSdk.getOwnersWhoApprovedTx(txHash) | ||
``` | ||
### createEnableFallbackHandlerTx | ||
Returns the Safe transaction to enable the fallback handler. | ||
```js | ||
const safeTransaction = await safeSdk.createEnableFallbackHandlerTx(fallbackHandlerAddress) | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
This method can optionally receive the `options` parameter: | ||
```js | ||
const options: SafeTransactionOptionalProps = { | ||
safeTxGas, // Optional | ||
baseGas, // Optional | ||
gasPrice, // Optional | ||
gasToken, // Optional | ||
refundReceiver, // Optional | ||
nonce // Optional | ||
} | ||
const safeTransaction = await safeSdk.createEnableFallbackHandlerTx(fallbackHandlerAddress, options) | ||
``` | ||
### createDisableFallbackHandlerTx | ||
Returns the Safe transaction to disable the fallback handler. | ||
```js | ||
const safeTransaction = await safeSdk.createDisableFallbackHandlerTx() | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
This method can optionally receive the `options` parameter: | ||
```js | ||
const options: SafeTransactionOptionalProps = { ... } | ||
const safeTransaction = await safeSdk.createDisableFallbackHandlerTx(options) | ||
``` | ||
### createEnableGuardTx | ||
Returns the Safe transaction to enable a Safe guard. | ||
```js | ||
const safeTransaction = await safeSdk.createEnableGuardTx(guardAddress) | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
This method can optionally receive the `options` parameter: | ||
```js | ||
const options: SafeTransactionOptionalProps = { | ||
safeTxGas, // Optional | ||
baseGas, // Optional | ||
gasPrice, // Optional | ||
gasToken, // Optional | ||
refundReceiver, // Optional | ||
nonce // Optional | ||
} | ||
const safeTransaction = await safeSdk.createEnableGuardTx(guardAddress, options) | ||
``` | ||
### createDisableGuardTx | ||
Returns the Safe transaction to disable a Safe guard. | ||
```js | ||
const safeTransaction = await safeSdk.createDisableGuardTx() | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
This method can optionally receive the `options` parameter: | ||
```js | ||
const options: SafeTransactionOptionalProps = { ... } | ||
const safeTransaction = await safeSdk.createDisableGuardTx(options) | ||
``` | ||
### createEnableModuleTx | ||
Returns a Safe transaction ready to be signed that will enable a Safe module. | ||
```js | ||
const safeTransaction = await safeSdk.createEnableModuleTx(moduleAddress) | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
This method can optionally receive the `options` parameter: | ||
```js | ||
const options: SafeTransactionOptionalProps = { ... } | ||
const safeTransaction = await safeSdk.createEnableModuleTx(moduleAddress, options) | ||
``` | ||
### createDisableModuleTx | ||
Returns a Safe transaction ready to be signed that will disable a Safe module. | ||
```js | ||
const safeTransaction = await safeSdk.createDisableModuleTx(moduleAddress) | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
This method can optionally receive the `options` parameter: | ||
```js | ||
const options: SafeTransactionOptionalProps = { ... } | ||
const safeTransaction = await safeSdk.createDisableModuleTx(moduleAddress, options) | ||
``` | ||
### createAddOwnerTx | ||
Returns the Safe transaction to add an owner and optionally change the threshold. | ||
```js | ||
const params: AddOwnerTxParams = { | ||
ownerAddress, | ||
threshold // Optional. If `threshold` is not provided the current threshold will not change. | ||
} | ||
const safeTransaction = await safeSdk.createAddOwnerTx(params) | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
This method can optionally receive the `options` parameter: | ||
```js | ||
const options: SafeTransactionOptionalProps = { ... } | ||
const safeTransaction = await safeSdk.createAddOwnerTx(params, options) | ||
``` | ||
### createRemoveOwnerTx | ||
Returns the Safe transaction to remove an owner and optionally change the threshold. | ||
```js | ||
const params: RemoveOwnerTxParams = { | ||
ownerAddress, | ||
newThreshold // Optional. If `newThreshold` is not provided, the current threshold will be decreased by one. | ||
} | ||
const safeTransaction = await safeSdk.createRemoveOwnerTx(params) | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
This method can optionally receive the `options` parameter: | ||
```js | ||
const options: SafeTransactionOptionalProps = { ... } | ||
const safeTransaction = await safeSdk.createRemoveOwnerTx(params, options) | ||
``` | ||
### createSwapOwnerTx | ||
Returns the Safe transaction to replace an owner of the Safe with a new one. | ||
```js | ||
const params: SwapOwnerTxParams = { | ||
oldOwnerAddress, | ||
newOwnerAddress | ||
} | ||
const safeTransaction = await safeSdk.createSwapOwnerTx(params) | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
This method can optionally receive the `options` parameter: | ||
```js | ||
const options: SafeTransactionOptionalProps = { ... } | ||
const safeTransaction = await safeSdk.createSwapOwnerTx(params, options) | ||
``` | ||
### createChangeThresholdTx | ||
Returns the Safe transaction to change the threshold. | ||
```js | ||
const safeTransaction = await safeSdk.createChangeThresholdTx(newThreshold) | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
This method can optionally receive the `options` parameter: | ||
```js | ||
const options: SafeTransactionOptionalProps = { ... } | ||
const safeTransaction = await safeSdk.createChangeThresholdTx(newThreshold, options) | ||
``` | ||
### isValidTransaction | ||
Checks if a Safe transaction can be executed successfully with no errors. | ||
```js | ||
const transactions: MetaTransactionData[] = [ | ||
{ | ||
// ... | ||
} | ||
] | ||
const safeTransaction = await safeSdk.createTransaction({ transactions }) | ||
const isValidTx = await safeSdk.isValidTransaction(safeTransaction) | ||
``` | ||
Optionally, some properties can be passed as execution options: | ||
```js | ||
const options: Web3TransactionOptions = { | ||
from, // Optional | ||
gas, // Optional | ||
gasPrice, // Optional | ||
maxFeePerGas, // Optional | ||
maxPriorityFeePerGas // Optional | ||
nonce // Optional | ||
} | ||
``` | ||
```js | ||
const options: EthersTransactionOptions = { | ||
from, // Optional | ||
gasLimit, // Optional | ||
gasPrice, // Optional | ||
maxFeePerGas, // Optional | ||
maxPriorityFeePerGas // Optional | ||
nonce // Optional | ||
} | ||
``` | ||
```js | ||
const isValidTx = await safeSdk.isValidTransaction(safeTransaction, options) | ||
``` | ||
### executeTransaction | ||
Executes a Safe transaction. | ||
```js | ||
const transactions: MetaTransactionData[] = [ | ||
{ | ||
// ... | ||
} | ||
] | ||
const safeTransaction = await safeSdk.createTransaction({ transactions }) | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction) | ||
await txResponse.transactionResponse?.wait() | ||
``` | ||
Optionally, some properties can be passed as execution options: | ||
```js | ||
const options: Web3TransactionOptions = { | ||
from, // Optional | ||
gas, // Optional | ||
gasPrice, // Optional | ||
maxFeePerGas, // Optional | ||
maxPriorityFeePerGas // Optional | ||
nonce // Optional | ||
} | ||
``` | ||
```js | ||
const options: EthersTransactionOptions = { | ||
from, // Optional | ||
gasLimit, // Optional | ||
gasPrice, // Optional | ||
maxFeePerGas, // Optional | ||
maxPriorityFeePerGas // Optional | ||
nonce // Optional | ||
} | ||
``` | ||
```js | ||
const txResponse = await safeSdk.executeTransaction(safeTransaction, options) | ||
``` | ||
## <a name="license">License</a> | ||
This library is released under MIT. | ||
## <a name="contributors">Contributors</a> | ||
- Germán Martínez ([germartinez](https://github.com/germartinez)) | ||
This library is [released under MIT](https://github.com/safe-global/safe-core-sdk/blob/main/LICENSE.md). |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
22
0
0
792182
9595
76
Updatedethers@^6.12.1
Updatedsemver@^7.6.1