fromAddress static method
Future<SafeContractController>
fromAddress({
- required ONREQUESTETHPROVIDER onRequestProvider,
- required SafeContractAssets assets,
- required ETHAddress address,
- BigInt? chainId,
Implementation
static Future<SafeContractController> fromAddress({
required ONREQUESTETHPROVIDER onRequestProvider,
required SafeContractAssets assets,
required ETHAddress address,
BigInt? chainId,
}) async {
final provider = await onRequestProvider();
chainId ??= await provider.request(EthereumRequestGetChainId());
Future<SafeContractController> getController() async {
final firstSlot = await provider.request(
EthereumRequestGetStorageAt(
address: address.address,
storageSlot: "0x00",
),
);
final singletonProxy =
ABIUtils.decodeSingle<SolidityAddress>(
type: "address",
bytes: BytesUtils.fromHexString(firstSlot),
).toEthereumAddress();
if (singletonProxy != ETHAddress.zero) {
final manifest = assets.fromSingletonAddress(singletonProxy);
return SafeContractController(
contract: SafeSingletonContract(
contract:
manifest
.getSafeSingletonManifestFromAddress(singletonProxy)
.abi,
contractAddress: address,
version: manifest.version,
),
onRequestProvider: onRequestProvider,
chainId: chainId!,
);
}
final chainIds = assets.getSupportedChainIds();
if (!chainIds.contains(chainId)) {
throw ETHPluginException(
"The provided chainId is not supported by Safe assets.",
details: {"chainId": chainId.toString()},
);
}
final manifest = assets.getLatestDeployment();
final contract = SafeSingletonContract(
contract: manifest.getSingletonContractAbi(),
contractAddress: address,
version: manifest.version,
);
try {
final storage = await contract.getStorageAt(
provider: provider,
offset: 0,
length: 1,
);
final singletonProxy =
ABIUtils.decodeSingle<SolidityAddress>(
type: "address",
bytes: storage,
).toEthereumAddress();
if (singletonProxy != ETHAddress.zero) {
final manifest = assets.fromSingletonAddress(singletonProxy);
return SafeContractController(
contract: SafeSingletonContract(
contract:
manifest
.getSafeSingletonManifestFromAddress(singletonProxy)
.abi,
contractAddress: address,
version: manifest.version,
),
onRequestProvider: onRequestProvider,
chainId: chainId!,
);
}
} on RPCError catch (_) {}
throw ETHPluginException(
"Unable to locate the ABI for the specified Safe Singleton address.",
details: {"address": address.address},
);
}
final controller = await getController();
final version = SafeContractVersion.fromVersion(
await controller.contract.getVersion(provider),
);
if (version == controller.contract.version) {
return controller;
}
throw ETHPluginException(
"Failed to verify the singleton contract address.",
);
}