UNPKG

@safe-global/protocol-kit

Version:

SDK that facilitates the interaction with Safe Smart Accounts

1,337 lines (1,321 loc) 176 kB
// test-utils/webauthnShim.ts import { p256 } from "@noble/curves/p256"; import { ethers } from "ethers"; import CBOR from "cbor"; function base64UrlEncode(data) { const buffer = typeof data === "string" ? Buffer.from(data.replace(/^0x/, ""), "hex") : Buffer.from(data); return buffer.toString("base64url"); } function userVerificationFlag(userVerification = "preferred") { switch (userVerification) { case "preferred": return 1; case "required": return 4; default: throw new Error(`user verification requirement ${userVerification} not supported`); } } function b2ab(buf) { return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); } function isEqualArray(a, b) { if (a.length != b.length) return false; for (let i = 0; i < a.length; i++) if (a[i] != b[i]) return false; return true; } function encodeWebAuthnSigningMessage(clientData, authenticatorData) { return ethers.getBytes( ethers.concat([ authenticatorData, ethers.sha256(ethers.toUtf8Bytes(JSON.stringify(clientData))) ]) ); } var Credential = class { constructor(rp, user, pk) { this.rp = rp; this.user = user; this.pk = pk || p256.utils.normPrivateKeyToScalar(p256.utils.randomPrivateKey()); this.id = ethers.dataSlice( ethers.keccak256(ethers.dataSlice(p256.getPublicKey(this.pk, false), 1)), 12 ); this.rawId = ethers.getBytes(this.id); } /** * Computes the COSE encoded public key for this credential. * See <https://datatracker.ietf.org/doc/html/rfc8152>. * * @returns Hex-encoded COSE-encoded public key */ cosePublicKey() { const pubk = p256.getPublicKey(this.pk, false); const x = pubk.subarray(1, 33); const y = pubk.subarray(33, 65); const key = /* @__PURE__ */ new Map(); key.set(-1, 1); key.set(-2, b2ab(x)); key.set(-3, b2ab(y)); key.set(1, 2); key.set(3, -7); return ethers.hexlify(CBOR.encode(key)); } }; var WebAuthnCredentials = class { /** * Creates a new instance of the WebAuthn credentials. * @param privateKey The private key to use for the credentials. If not provided, a random key will be generated. */ constructor(privateKey) { this.privateKey = privateKey; this.credentials = []; } /** * This is a shim for `navigator.credentials.create` method. * See <https://w3c.github.io/webappsec-credential-management/#dom-credentialscontainer-create>. * * @param options The public key credential creation options. * @returns A public key credential with an attestation response. */ create({ publicKey }) { if (!publicKey.pubKeyCredParams.some(({ alg }) => alg === -7)) { throw new Error("unsupported signature algorithm(s)"); } const credential = new Credential(publicKey.rp.id, publicKey.user.id, this.privateKey); this.credentials.push(credential); const clientData = { type: "webauthn.create", challenge: base64UrlEncode(publicKey.challenge), origin: `https://${publicKey.rp.id}` }; const attestationObject = { authData: b2ab( ethers.getBytes( ethers.solidityPacked( ["bytes32", "uint8", "uint32", "bytes16", "uint16", "bytes", "bytes"], [ ethers.sha256(ethers.toUtf8Bytes(publicKey.rp.id)), 64 + userVerificationFlag(publicKey.userVerification), // flags = attested_data + user_present 0, // signCount `0x${"42".repeat(16)}`, // aaguid ethers.dataLength(credential.id), credential.id, credential.cosePublicKey() ] ) ) ), fmt: "none", attStmt: {} }; return { id: base64UrlEncode(credential.rawId), rawId: credential.rawId.slice(), response: { clientDataJSON: b2ab(ethers.toUtf8Bytes(JSON.stringify(clientData))), attestationObject: b2ab(CBOR.encode(attestationObject)), getPublicKey: () => b2ab(p256.getPublicKey(credential.pk, false)) }, type: "public-key" }; } /** * This is a shim for `navigator.credentials.get` method. * See <https://w3c.github.io/webappsec-credential-management/#dom-credentialscontainer-get>. * * @param options The public key credential request options. * @returns A public key credential with an assertion response. */ get({ publicKey }) { const credential = publicKey.allowCredentials.flatMap(({ id }) => this.credentials.filter((c) => isEqualArray(c.rawId, id))).at(0); if (credential === void 0) { throw new Error("credential not found"); } const clientData = { type: "webauthn.get", challenge: base64UrlEncode(publicKey.challenge), origin: `https://${credential.rp}` }; const authenticatorData = ethers.solidityPacked( ["bytes32", "uint8", "uint32"], [ ethers.sha256(ethers.toUtf8Bytes(credential.rp)), userVerificationFlag(publicKey.userVerification), // flags = user_present 0 // signCount ] ); const message = encodeWebAuthnSigningMessage(clientData, authenticatorData); const signature = p256.sign(message, credential.pk, { lowS: false, prehash: true }); return { id: base64UrlEncode(credential.rawId), rawId: credential.rawId.slice(), response: { clientDataJSON: b2ab(ethers.toUtf8Bytes(JSON.stringify(clientData))), authenticatorData: b2ab(ethers.getBytes(authenticatorData)), signature: b2ab(signature.toDERRawBytes(false)), userHandle: credential.user }, type: "public-key" }; } }; // test-utils/passkeys.ts import { keccak256 as keccak2563, toBytes as toBytes4 } from "viem"; // src/utils/types.ts import { isHex, defineChain, etherUnits } from "viem"; import * as allChains from "viem/chains"; function asHash(hash) { return hash; } function asHex(hex) { return isHex(hex) ? hex : `0x${hex}`; } function getChainById(chainId) { const chain = Object.values(allChains).find((chain2) => chain2.id === Number(chainId)); if (chain) { return chain; } else { return defineChain({ id: Number(chainId), name: "Custom", nativeCurrency: { decimals: etherUnits.wei, name: "Ether", symbol: "ETH" }, rpcUrls: { default: { http: [], webSocket: [] } } }); } } // src/utils/constants.ts import { zeroAddress } from "viem"; var SENTINEL_ADDRESS = "0x0000000000000000000000000000000000000001"; // src/utils/address.ts function sameString(str1, str2) { return !!str1 && !!str2 && str1.toLowerCase() === str2.toLowerCase(); } function isSentinelAddress(address) { return sameString(address, SENTINEL_ADDRESS); } // src/utils/eip-3770/index.ts import { isAddress } from "viem"; // src/utils/eip-3770/config.ts var networks = [ { chainId: 1n, shortName: "eth" }, { chainId: 3n, shortName: "rop" }, { chainId: 4n, shortName: "rin" }, { chainId: 5n, shortName: "gor" }, { chainId: 10n, shortName: "oeth" }, { chainId: 11n, shortName: "meta" }, { chainId: 12n, shortName: "kal" }, { chainId: 14n, shortName: "flr" }, { chainId: 16n, shortName: "cflr" }, { chainId: 18n, shortName: "tst" }, { chainId: 19n, shortName: "sgb" }, { chainId: 25n, shortName: "cro" }, { chainId: 28n, shortName: "bobarinkeby" }, { chainId: 30n, shortName: "rsk" }, { chainId: 31n, shortName: "trsk" }, { chainId: 39n, shortName: "u2u" }, { chainId: 40n, shortName: "telosevm" }, { chainId: 41n, shortName: "telosevmtestnet" }, { chainId: 42n, shortName: "lukso" }, { chainId: 43n, shortName: "pangolin" }, { chainId: 44n, shortName: "crab" }, { chainId: 46n, shortName: "darwinia" }, { chainId: 50n, shortName: "xdc" }, { chainId: 51n, shortName: "txdc" }, { chainId: 56n, shortName: "bnb" }, { chainId: 57n, shortName: "sys" }, { chainId: 61n, shortName: "etc" }, { chainId: 63n, shortName: "metc" }, { chainId: 69n, shortName: "okov" }, { chainId: 71n, shortName: "cfxtest" }, { chainId: 81n, shortName: "joc" }, { chainId: 82n, shortName: "meter" }, { chainId: 83n, shortName: "meter-test" }, { chainId: 88n, shortName: "vic" }, { chainId: 96n, shortName: "bkc" }, { chainId: 97n, shortName: "bnbt" }, { chainId: 98n, shortName: "six" }, { chainId: 100n, shortName: "gno" }, { chainId: 106n, shortName: "vlx" }, { chainId: 108n, shortName: "tt" }, { chainId: 109n, shortName: "shibariumecosystem" }, { chainId: 111n, shortName: "etl" }, { chainId: 114n, shortName: "c2flr" }, { chainId: 122n, shortName: "fuse" }, { chainId: 123n, shortName: "spark" }, { chainId: 130n, shortName: "unichain" }, { chainId: 133n, shortName: "HSKT" }, { chainId: 137n, shortName: "matic" }, { chainId: 143n, shortName: "mon" }, { chainId: 146n, shortName: "sonic" }, { chainId: 148n, shortName: "shimmerevm" }, { chainId: 150n, shortName: "sixt" }, { chainId: 151n, shortName: "rbn" }, { chainId: 153n, shortName: "rbn-testnet" }, { chainId: 155n, shortName: "tenet-testnet" }, { chainId: 169n, shortName: "manta" }, { chainId: 173n, shortName: "eni" }, { chainId: 177n, shortName: "hsk" }, { chainId: 179n, shortName: "abey" }, { chainId: 181n, shortName: "water" }, { chainId: 185n, shortName: "mint" }, { chainId: 195n, shortName: "tokb" }, { chainId: 196n, shortName: "okb" }, { chainId: 204n, shortName: "opbnb" }, { chainId: 228n, shortName: "fhe" }, { chainId: 232n, shortName: "lens" }, { chainId: 239n, shortName: "tacchain" }, { chainId: 240n, shortName: "zkTCRO" }, { chainId: 246n, shortName: "ewt" }, { chainId: 250n, shortName: "ftm" }, { chainId: 252n, shortName: "fraxtal" }, { chainId: 255n, shortName: "kroma" }, { chainId: 274n, shortName: "lachain" }, { chainId: 280n, shortName: "zksync-goerli" }, { chainId: 282n, shortName: "deprecated-zkTCRO" }, { chainId: 288n, shortName: "boba" }, { chainId: 291n, shortName: "orderly" }, { chainId: 295n, shortName: "hedera-mainnet" }, { chainId: 296n, shortName: "hedera-testnet" }, { chainId: 300n, shortName: "zksync-sepolia" }, { chainId: 314n, shortName: "filecoin" }, { chainId: 321n, shortName: "kcs" }, { chainId: 322n, shortName: "kcst" }, { chainId: 324n, shortName: "zksync" }, { chainId: 336n, shortName: "sdn" }, { chainId: 338n, shortName: "tcro" }, { chainId: 360n, shortName: "shape" }, { chainId: 369n, shortName: "pls" }, { chainId: 388n, shortName: "zkCRO" }, { chainId: 418n, shortName: "latestnet" }, { chainId: 420n, shortName: "ogor" }, { chainId: 424n, shortName: "PGN" }, { chainId: 466n, shortName: "appchain" }, { chainId: 478n, shortName: "formnetwork" }, { chainId: 480n, shortName: "wc" }, { chainId: 530n, shortName: "pundiai" }, { chainId: 545n, shortName: "flow-testnet" }, { chainId: 570n, shortName: "sys-rollux" }, { chainId: 588n, shortName: "metis-stardust" }, { chainId: 592n, shortName: "astr" }, { chainId: 595n, shortName: "maca" }, { chainId: 599n, shortName: "metis-goerli" }, { chainId: 648n, shortName: "ace" }, { chainId: 686n, shortName: "kar" }, { chainId: 690n, shortName: "redstone" }, { chainId: 698n, shortName: "Matchain" }, { chainId: 747n, shortName: "flow-mainnet" }, { chainId: 756n, shortName: "capx-testnet" }, { chainId: 757n, shortName: "capx" }, { chainId: 787n, shortName: "aca" }, { chainId: 841n, shortName: "tara" }, { chainId: 842n, shortName: "taratest" }, { chainId: 870n, shortName: "AMN" }, { chainId: 919n, shortName: "modesep" }, { chainId: 938n, shortName: "haust" }, { chainId: 943n, shortName: "t4pls" }, { chainId: 964n, shortName: "bittensor-evm-mainnet" }, { chainId: 970n, shortName: "ccn" }, { chainId: 988n, shortName: "stable" }, { chainId: 995n, shortName: "5ire" }, { chainId: 999n, shortName: "hyper_evm" }, { chainId: 1001n, shortName: "kaia-kairos" }, { chainId: 1008n, shortName: "eun" }, { chainId: 1030n, shortName: "cfx" }, { chainId: 1088n, shortName: "metis-andromeda" }, { chainId: 1101n, shortName: "zkevm" }, { chainId: 1111n, shortName: "wemix" }, { chainId: 1112n, shortName: "twemix" }, { chainId: 1114n, shortName: "tcore2" }, { chainId: 1115n, shortName: "tcore" }, { chainId: 1116n, shortName: "core" }, { chainId: 1125n, shortName: "taker" }, { chainId: 1135n, shortName: "lisk" }, { chainId: 1230n, shortName: "UltronTestnet" }, { chainId: 1231n, shortName: "UltronMainnet" }, { chainId: 1284n, shortName: "mbeam" }, { chainId: 1285n, shortName: "mriver" }, { chainId: 1287n, shortName: "mbase" }, { chainId: 1294n, shortName: "bobabeam" }, { chainId: 1301n, shortName: "unichain-sep" }, { chainId: 1315n, shortName: "story-aeneid" }, { chainId: 1328n, shortName: "sei-testnet" }, { chainId: 1329n, shortName: "sei" }, { chainId: 1337n, shortName: "geth" }, { chainId: 1424n, shortName: "perennial" }, { chainId: 1439n, shortName: "injective-testnet" }, { chainId: 1442n, shortName: "testnet-zkEVM-mango" }, { chainId: 1480n, shortName: "vana" }, { chainId: 1513n, shortName: "Story" }, { chainId: 1514n, shortName: "sty" }, { chainId: 1516n, shortName: "story-testnet" }, { chainId: 1559n, shortName: "tenet" }, { chainId: 1625n, shortName: "gravity" }, { chainId: 1663n, shortName: "Gobi" }, { chainId: 1672n, shortName: "pharos" }, { chainId: 1729n, shortName: "reya" }, { chainId: 1740n, shortName: "metall2-testnet" }, { chainId: 1750n, shortName: "metall2" }, { chainId: 1776n, shortName: "injective" }, { chainId: 1807n, shortName: "rana" }, { chainId: 1811n, shortName: "lif3-testnet" }, { chainId: 1868n, shortName: "soneium" }, { chainId: 1890n, shortName: "lightlink_phoenix" }, { chainId: 1891n, shortName: "lightlink_pegasus" }, { chainId: 1923n, shortName: "swellchain" }, { chainId: 1924n, shortName: "swellchain-sep" }, { chainId: 1946n, shortName: "soneium-minato" }, { chainId: 1984n, shortName: "euntest" }, { chainId: 1995n, shortName: "edxt" }, { chainId: 1998n, shortName: "kyoto-testnet" }, { chainId: 2000n, shortName: "dc" }, { chainId: 2001n, shortName: "milkada" }, { chainId: 2002n, shortName: "milkalgo" }, { chainId: 2008n, shortName: "cloudwalk_testnet" }, { chainId: 2019n, shortName: "pmint_test" }, { chainId: 2020n, shortName: "pmint" }, { chainId: 2021n, shortName: "edg" }, { chainId: 2039n, shortName: "aleph" }, { chainId: 2187n, shortName: "g7" }, { chainId: 2192n, shortName: "snax" }, { chainId: 2201n, shortName: "stable-testnet" }, { chainId: 2221n, shortName: "tkava" }, { chainId: 2222n, shortName: "kava" }, { chainId: 2331n, shortName: "rss3-testnet" }, { chainId: 2345n, shortName: "goat" }, { chainId: 2358n, shortName: "kroma-sepolia" }, { chainId: 2390n, shortName: "tacchain_2390-1" }, { chainId: 2391n, shortName: "tacchain_2391-1" }, { chainId: 2424n, shortName: "inevm-testnet" }, { chainId: 2442n, shortName: "zkevm-testnet-cardona" }, { chainId: 2522n, shortName: "fraxtal-testnet" }, { chainId: 2741n, shortName: "abstract" }, { chainId: 2787n, shortName: "creator-chain-mainnet" }, { chainId: 2810n, shortName: "hmorph" }, { chainId: 2818n, shortName: "morph" }, { chainId: 2910n, shortName: "morph-hoodi-testnet" }, { chainId: 3068n, shortName: "bfc" }, { chainId: 3111n, shortName: "alpha" }, { chainId: 3338n, shortName: "PEAQ" }, { chainId: 3501n, shortName: "JFIN" }, { chainId: 3636n, shortName: "BTNXt" }, { chainId: 3637n, shortName: "BTNX" }, { chainId: 3737n, shortName: "csb" }, { chainId: 3776n, shortName: "astrzk" }, { chainId: 4002n, shortName: "tftm" }, { chainId: 4061n, shortName: "Nahmii3Mainnet" }, { chainId: 4062n, shortName: "Nahmii3Testnet" }, { chainId: 4078n, shortName: "muster" }, { chainId: 4153n, shortName: "rise" }, { chainId: 4157n, shortName: "crossfi-testnet" }, { chainId: 4158n, shortName: "crossfi" }, { chainId: 4162n, shortName: "SXR" }, { chainId: 4202n, shortName: "lisksep" }, { chainId: 4217n, shortName: "tempo" }, { chainId: 4326n, shortName: "megaeth" }, { chainId: 4337n, shortName: "beam" }, { chainId: 4460n, shortName: "orderlyl2" }, { chainId: 4488n, shortName: "HYDRA" }, { chainId: 4509n, shortName: "SC" }, { chainId: 4653n, shortName: "gold" }, { chainId: 4661n, shortName: "appchaintestnet" }, { chainId: 4689n, shortName: "iotex-mainnet" }, { chainId: 4801n, shortName: "wcsep" }, { chainId: 4918n, shortName: "txvm" }, { chainId: 4919n, shortName: "xvm" }, { chainId: 5000n, shortName: "mantle" }, { chainId: 5001n, shortName: "mantle-testnet" }, { chainId: 5003n, shortName: "mnt-sep" }, { chainId: 5031n, shortName: "Somnia" }, { chainId: 5115n, shortName: "citrea-testnet" }, { chainId: 5165n, shortName: "ftn" }, { chainId: 5330n, shortName: "sseed" }, { chainId: 5464n, shortName: "saga" }, { chainId: 5611n, shortName: "obnbt" }, { chainId: 5700n, shortName: "tsys" }, { chainId: 5851n, shortName: "OntologyTestnet" }, { chainId: 5887n, shortName: "dukong" }, { chainId: 5888n, shortName: "mantrachain" }, { chainId: 6001n, shortName: "bouncebit-mainnet" }, { chainId: 6102n, shortName: "cascadia" }, { chainId: 6321n, shortName: "eaura" }, { chainId: 6322n, shortName: "aura" }, { chainId: 6342n, shortName: "megatest" }, { chainId: 6398n, shortName: "connext-sepolia" }, { chainId: 6688n, shortName: "iris" }, { chainId: 6880n, shortName: "mtt-network" }, { chainId: 6900n, shortName: "cataclysm-1" }, { chainId: 6911n, shortName: "nibiru-testnet-2" }, { chainId: 6942n, shortName: "laika" }, { chainId: 7000n, shortName: "zetachain-mainnet" }, { chainId: 7001n, shortName: "zetachain-testnet" }, { chainId: 7070n, shortName: "planq" }, { chainId: 7171n, shortName: "bitrock" }, { chainId: 7200n, shortName: "xsat" }, { chainId: 7208n, shortName: "nxra-mainnet" }, { chainId: 7332n, shortName: "EON" }, { chainId: 7336n, shortName: "pruvtestnet" }, { chainId: 7337n, shortName: "pruvmainnet" }, { chainId: 7341n, shortName: "shyft" }, { chainId: 7560n, shortName: "cyeth" }, { chainId: 7700n, shortName: "canto" }, { chainId: 7771n, shortName: "tbitrock" }, { chainId: 7897n, shortName: "arena-z" }, { chainId: 7979n, shortName: "dos" }, { chainId: 8008n, shortName: "polynomial" }, { chainId: 8150n, shortName: "alpen" }, { chainId: 8192n, shortName: "tqf" }, { chainId: 8194n, shortName: "ttqf" }, { chainId: 8217n, shortName: "kaia-mainnet" }, { chainId: 8329n, shortName: "lrz" }, { chainId: 8333n, shortName: "b3" }, { chainId: 8408n, shortName: "zentest" }, { chainId: 8453n, shortName: "base" }, { chainId: 8700n, shortName: "ACN" }, { chainId: 8765n, shortName: "ward" }, { chainId: 8801n, shortName: "okto-testnet" }, { chainId: 8822n, shortName: "iotaevm" }, { chainId: 8844n, shortName: "THYDRA" }, { chainId: 9000n, shortName: "evmos-testnet" }, { chainId: 9001n, shortName: "evmos" }, { chainId: 9069n, shortName: "AP3X" }, { chainId: 9070n, shortName: "tAP3X" }, { chainId: 9369n, shortName: "z" }, { chainId: 9700n, shortName: "MainnetDev" }, { chainId: 9728n, shortName: "boba-testnet" }, { chainId: 9745n, shortName: "plasma" }, { chainId: 9746n, shortName: "plasma-testnet" }, { chainId: 10000n, shortName: "smartbch" }, { chainId: 10001n, shortName: "smartbchtest" }, { chainId: 10081n, shortName: "joct" }, { chainId: 10143n, shortName: "mon-testnet" }, { chainId: 10200n, shortName: "chi" }, { chainId: 10242n, shortName: "aa" }, { chainId: 10243n, shortName: "aat" }, { chainId: 10849n, shortName: "lamina1" }, { chainId: 10888n, shortName: "gameswift-chain-testnet" }, { chainId: 11011n, shortName: "shapesep" }, { chainId: 11111n, shortName: "WAGMI" }, { chainId: 11124n, shortName: "abstract-sepolia" }, { chainId: 11235n, shortName: "islm" }, { chainId: 11417n, shortName: "anq-testnet" }, { chainId: 11437n, shortName: "shyftt" }, { chainId: 11501n, shortName: "bevm" }, { chainId: 11503n, shortName: "bevm-test" }, { chainId: 11820n, shortName: "artela-mainnet" }, { chainId: 11891n, shortName: "Arianee" }, { chainId: 12324n, shortName: "l3x" }, { chainId: 12325n, shortName: "l3x-testnet" }, { chainId: 12357n, shortName: "rei-testnet" }, { chainId: 12553n, shortName: "rss3" }, { chainId: 13337n, shortName: "beam-testnet" }, { chainId: 13371n, shortName: "imx" }, { chainId: 13441n, shortName: "bridgeless" }, { chainId: 13473n, shortName: "imx-testnet" }, { chainId: 13505n, shortName: "gravitysep" }, { chainId: 13746n, shortName: "g7t" }, { chainId: 14601n, shortName: "sonic-testnet" }, { chainId: 14800n, shortName: "vana-moksha" }, { chainId: 16661n, shortName: "0g" }, { chainId: 17000n, shortName: "holesky" }, { chainId: 17069n, shortName: "garnet" }, { chainId: 17172n, shortName: "eclipse" }, { chainId: 18231n, shortName: "unreal-old" }, { chainId: 18233n, shortName: "unreal" }, { chainId: 18880n, shortName: "expchain" }, { chainId: 20994n, shortName: "fluent-testnet" }, { chainId: 22776n, shortName: "mapo" }, { chainId: 23294n, shortName: "sapphire" }, { chainId: 23295n, shortName: "sapphire-testnet" }, { chainId: 24101n, shortName: "incentiv" }, { chainId: 25327n, shortName: "Everclear" }, { chainId: 25363n, shortName: "fluent" }, { chainId: 26888n, shortName: "tABCore" }, { chainId: 28802n, shortName: "tcent" }, { chainId: 28882n, shortName: "BobaSepolia" }, { chainId: 28979n, shortName: "kimbonet-testnet" }, { chainId: 30303n, shortName: "Ethiq" }, { chainId: 31611n, shortName: "mezo-testnet" }, { chainId: 31612n, shortName: "mezo" }, { chainId: 32323n, shortName: "basedai" }, { chainId: 32380n, shortName: "paix" }, { chainId: 32769n, shortName: "zil" }, { chainId: 32770n, shortName: "zq2-proto-mainnet" }, { chainId: 33101n, shortName: "zil-testnet" }, { chainId: 33111n, shortName: "curtis" }, { chainId: 33139n, shortName: "apechain" }, { chainId: 33401n, shortName: "slingshot" }, { chainId: 34443n, shortName: "mode" }, { chainId: 35441n, shortName: "q" }, { chainId: 35443n, shortName: "q-testnet" }, { chainId: 36888n, shortName: "abcore" }, { chainId: 36900n, shortName: "adi" }, { chainId: 37111n, shortName: "lens-sepolia" }, { chainId: 41455n, shortName: "aleph-zero" }, { chainId: 41923n, shortName: "edu-chain" }, { chainId: 42161n, shortName: "arb1" }, { chainId: 42170n, shortName: "arb-nova" }, { chainId: 42220n, shortName: "celo" }, { chainId: 42421n, shortName: "rwa" }, { chainId: 42431n, shortName: "tempo-moderato" }, { chainId: 42793n, shortName: "etlk" }, { chainId: 43111n, shortName: "hemi" }, { chainId: 43113n, shortName: "fuji" }, { chainId: 43114n, shortName: "avax" }, { chainId: 43288n, shortName: "boba-avax" }, { chainId: 43419n, shortName: "gunz-mainnet" }, { chainId: 44787n, shortName: "alfa" }, { chainId: 45000n, shortName: "autobahnnetwork" }, { chainId: 47763n, shortName: "neox-mainnet" }, { chainId: 47805n, shortName: "rei" }, { chainId: 48898n, shortName: "zircuit-garfield-testnet" }, { chainId: 48899n, shortName: "zircuit-testnet" }, { chainId: 48900n, shortName: "zircuit-mainnet" }, { chainId: 49088n, shortName: "tbfc" }, { chainId: 49321n, shortName: "Stork" }, { chainId: 50104n, shortName: "sophon" }, { chainId: 50312n, shortName: "SomniaTestnet" }, { chainId: 52924n, shortName: "lazai" }, { chainId: 53302n, shortName: "seedsep" }, { chainId: 53456n, shortName: "birdlayer" }, { chainId: 53457n, shortName: "dodochain" }, { chainId: 54211n, shortName: "islmt" }, { chainId: 55244n, shortName: "spn" }, { chainId: 56288n, shortName: "boba-bnb" }, { chainId: 57000n, shortName: "tsys-rollux" }, { chainId: 57054n, shortName: "blaze" }, { chainId: 57073n, shortName: "ink" }, { chainId: 58008n, shortName: "sepPGN" }, { chainId: 59140n, shortName: "linea-goerli" }, { chainId: 59141n, shortName: "linea-sepolia" }, { chainId: 59144n, shortName: "linea" }, { chainId: 59902n, shortName: "metis-sepolia" }, { chainId: 60808n, shortName: "bob" }, { chainId: 61166n, shortName: "treasure" }, { chainId: 66665n, shortName: "ceth" }, { chainId: 71401n, shortName: "gw-testnet-v1" }, { chainId: 71402n, shortName: "gw-mainnet-v1" }, { chainId: 72080n, shortName: "nxra-testnet" }, { chainId: 73799n, shortName: "vt" }, { chainId: 80001n, shortName: "maticmum" }, { chainId: 80002n, shortName: "polygonamoy" }, { chainId: 80069n, shortName: "berachain-bepolia" }, { chainId: 80084n, shortName: "berachainbArtio" }, { chainId: 80085n, shortName: "berachainArtio" }, { chainId: 80094n, shortName: "berachain" }, { chainId: 81224n, shortName: "Codex" }, { chainId: 81457n, shortName: "blastmainnet" }, { chainId: 83291n, shortName: "lrz-testnet" }, { chainId: 84531n, shortName: "basegor" }, { chainId: 84532n, shortName: "basesep" }, { chainId: 88811n, shortName: "unit0-mainnet" }, { chainId: 88817n, shortName: "unit0-testnet" }, { chainId: 88882n, shortName: "chzspicy" }, { chainId: 88888n, shortName: "chiliz" }, { chainId: 90001n, shortName: "dhobyghaut" }, { chainId: 91342n, shortName: "giwasepolia" }, { chainId: 97435n, shortName: "sling" }, { chainId: 98864n, shortName: "plume-devnet" }, { chainId: 98865n, shortName: "plume" }, { chainId: 98866n, shortName: "plume-mainnet" }, { chainId: 98867n, shortName: "plume-testnet" }, { chainId: 98875n, shortName: "nil" }, { chainId: 98985n, shortName: "superposition-testnet" }, { chainId: 102030n, shortName: "ctc" }, { chainId: 103454n, shortName: "masatest" }, { chainId: 105105n, shortName: "stratis" }, { chainId: 111188n, shortName: "re-al" }, { chainId: 127823n, shortName: "etls" }, { chainId: 128123n, shortName: "etlt" }, { chainId: 167000n, shortName: "tko-mainnet" }, { chainId: 167008n, shortName: "tko-katla" }, { chainId: 167009n, shortName: "tko-hekla" }, { chainId: 167013n, shortName: "tko-hoodi" }, { chainId: 175188n, shortName: "lpy" }, { chainId: 181228n, shortName: "hpp-sepolia" }, { chainId: 190415n, shortName: "hpp-mainnet" }, { chainId: 200101n, shortName: "milktada" }, { chainId: 200202n, shortName: "milktalgo" }, { chainId: 200810n, shortName: "btrt" }, { chainId: 200901n, shortName: "btr" }, { chainId: 205205n, shortName: "auroria" }, { chainId: 210425n, shortName: "platon" }, { chainId: 222888n, shortName: "mocat" }, { chainId: 278701n, shortName: "creator-chain-testnet" }, { chainId: 314159n, shortName: "filecoin-calibration" }, { chainId: 325000n, shortName: "CampV2" }, { chainId: 328527n, shortName: "nal" }, { chainId: 333999n, shortName: "olympus" }, { chainId: 369369n, shortName: "den-mainnet" }, { chainId: 381931n, shortName: "metal" }, { chainId: 421611n, shortName: "arb-rinkeby" }, { chainId: 421613n, shortName: "arb-goerli" }, { chainId: 421614n, shortName: "arb-sep" }, { chainId: 444444n, shortName: "syndr" }, { chainId: 490000n, shortName: "ATN" }, { chainId: 511111n, shortName: "alpha-testnet" }, { chainId: 534351n, shortName: "scr-sepolia" }, { chainId: 534352n, shortName: "scr" }, { chainId: 534353n, shortName: "scr-alpha" }, { chainId: 543210n, shortName: "zero-network" }, { chainId: 555666n, shortName: "eclipset" }, { chainId: 560048n, shortName: "hoe" }, { chainId: 622277n, shortName: "rth" }, { chainId: 656476n, shortName: "open-campus-codex" }, { chainId: 657468n, shortName: "ethereal-testnet" }, { chainId: 660279n, shortName: "xai" }, { chainId: 668668n, shortName: "cnw" }, { chainId: 688688n, shortName: "pharos-testnet" }, { chainId: 688689n, shortName: "pharos-atlantic" }, { chainId: 695569n, shortName: "pyrope" }, { chainId: 713715n, shortName: "sei-devnet" }, { chainId: 743111n, shortName: "hemi-sep" }, { chainId: 747474n, shortName: "katana" }, { chainId: 763373n, shortName: "inksepolia" }, { chainId: 763375n, shortName: "surge-testnet" }, { chainId: 764984n, shortName: "lamina1test" }, { chainId: 808813n, shortName: "bob-sepolia" }, { chainId: 810180n, shortName: "zklink-nova" }, { chainId: 839999n, shortName: "txsat" }, { chainId: 853211n, shortName: "haqq-testethiq" }, { chainId: 978657n, shortName: "treasure-ruby" }, { chainId: 984122n, shortName: "forma" }, { chainId: 1000101n, shortName: "xo" }, { chainId: 1440000n, shortName: "xrplevm" }, { chainId: 1449000n, shortName: "xrplevmtestnet" }, { chainId: 1501869n, shortName: "water9" }, { chainId: 2206132n, shortName: "platondev2" }, { chainId: 2632500n, shortName: "coti" }, { chainId: 3441006n, shortName: "mantaSepoliaTestnet" }, { chainId: 4457845n, shortName: "zero-sepolia" }, { chainId: 5042002n, shortName: "arc-testnet" }, { chainId: 5064014n, shortName: "ethereal" }, { chainId: 6038361n, shortName: "azkyt" }, { chainId: 6281971n, shortName: "dogeos-chykyu" }, { chainId: 6985385n, shortName: "hp" }, { chainId: 7225878n, shortName: "saakuru" }, { chainId: 7777777n, shortName: "zora" }, { chainId: 9999999n, shortName: "fluence" }, { chainId: 11142220n, shortName: "celo-sep" }, { chainId: 11155111n, shortName: "sep" }, { chainId: 11155420n, shortName: "opsep" }, { chainId: 11155931n, shortName: "rise-testnet" }, { chainId: 12227332n, shortName: "neox-t4" }, { chainId: 13374202n, shortName: "ethereal-testnet-0" }, { chainId: 13863860n, shortName: "sis" }, { chainId: 20250407n, shortName: "platondev3" }, { chainId: 21000000n, shortName: "corn" }, { chainId: 52164803n, shortName: "fluence-testnet" }, { chainId: 65100004n, shortName: "piccadilly-04" }, { chainId: 94204209n, shortName: "polygon-blackberry" }, { chainId: 111557560n, shortName: "cysep" }, { chainId: 123420111n, shortName: "opcelestia-raspberry" }, { chainId: 161221135n, shortName: "plume-testnet-legacy" }, { chainId: 168587773n, shortName: "blastsepolia" }, { chainId: 222000222n, shortName: "kanazawa" }, { chainId: 245022926n, shortName: "neonevm-devnet" }, { chainId: 245022934n, shortName: "neonevm-mainnet" }, { chainId: 253368190n, shortName: "flame" }, { chainId: 328527624n, shortName: "nalsep" }, { chainId: 333000333n, shortName: "meld" }, { chainId: 476462898n, shortName: "Skopje" }, { chainId: 531050104n, shortName: "sophon-testnet" }, { chainId: 531050204n, shortName: "sophon-os-testnet" }, { chainId: 666666666n, shortName: "degen-chain" }, { chainId: 888888888n, shortName: "ancient8" }, { chainId: 994873017n, shortName: "lumia-mainnet" }, { chainId: 999999999n, shortName: "zsep" }, { chainId: 1313161554n, shortName: "aurora" }, { chainId: 1313161555n, shortName: "aurora-testnet" }, { chainId: 1417429182n, shortName: "zephyr" }, { chainId: 1511670449n, shortName: "GPT" }, { chainId: 1570754601n, shortName: "hst-test" }, { chainId: 1660990954n, shortName: "sn-sepolia" }, { chainId: 1666600000n, shortName: "hmy-s0" }, { chainId: 1666700000n, shortName: "hmy-b-s0" }, { chainId: 1952959480n, shortName: "lumiatestnet" }, { chainId: 2030232745n, shortName: "lumia-beam-testnet" }, { chainId: 3735928814n, shortName: "edent" }, { chainId: 11297108099n, shortName: "tpalm" }, { chainId: 11297108109n, shortName: "palm" }, { chainId: 30143370385n, shortName: "BUB" }, { chainId: 37714555429n, shortName: "xaitestnet" }, { chainId: 88153591557n, shortName: "arb-blueberry" }, { chainId: 123420000220n, shortName: "fluence-stage" }, { chainId: 920637907288165n, shortName: "kkrt-starknet-sepolia" } ]; try { if (process.env.TEST_NETWORK === "hardhat") { networks.push({ shortName: "local", chainId: 31337n }); } } catch { } // src/utils/eip-3770/index.ts function parseEip3770Address(fullAddress) { const parts = fullAddress.split(":"); const address = parts.length > 1 ? parts[1] : parts[0]; const prefix = parts.length > 1 ? parts[0] : ""; return { prefix, address }; } function getEip3770NetworkPrefixFromChainId(chainId) { const network = networks.find((network2) => chainId === network2.chainId); if (!network) { throw new Error("No network prefix supported for the current chainId"); } return network.shortName; } function isValidEip3770NetworkPrefix(prefix) { return networks.some(({ shortName }) => shortName === prefix); } function validateEip3770NetworkPrefix(prefix, currentChainId) { const isCurrentNetworkPrefix = prefix === getEip3770NetworkPrefixFromChainId(currentChainId); if (!isValidEip3770NetworkPrefix(prefix) || !isCurrentNetworkPrefix) { throw new Error("The network prefix must match the current network"); } } function validateEthereumAddress(address) { if (!isAddress(address)) { throw new Error(`Invalid Ethereum address ${address}`); } } function validateEip3770Address(fullAddress, currentChainId) { const { address, prefix } = parseEip3770Address(fullAddress); validateEthereumAddress(address); if (prefix) { validateEip3770NetworkPrefix(prefix, currentChainId); } return { address, prefix }; } // src/utils/eip-712/index.ts import { hashMessage as performMessageHash } from "viem"; import semverSatisfies from "semver/functions/satisfies.js"; // src/utils/eip-712/encode.ts import { keccak256, concat, encodeAbiParameters, getTypesForEIP712Domain, validateTypedData, hashDomain, toHex } from "viem"; function encodeField({ types, name, type, value }) { if (types[type] !== void 0) { return [{ type: "bytes32" }, keccak256(encodeData({ data: value, primaryType: type, types }))]; } if (type === "bytes") { const prepend = value.length % 2 ? "0" : ""; value = `0x${prepend + value.slice(2)}`; return [{ type: "bytes32" }, keccak256(value)]; } if (type === "string") return [{ type: "bytes32" }, keccak256(toHex(value))]; if (type.lastIndexOf("]") === type.length - 1) { const parsedType = type.slice(0, type.lastIndexOf("[")); const typeValuePairs = value.map( (item) => encodeField({ name, type: parsedType, types, value: item }) ); return [ { type: "bytes32" }, keccak256( encodeAbiParameters( typeValuePairs.map(([t]) => t), typeValuePairs.map(([, v]) => v) ) ) ]; } return [{ type }, value]; } function findTypeDependencies({ primaryType: primaryType_, types }, results = /* @__PURE__ */ new Set()) { const match = primaryType_.match(/^\w*/u); const primaryType = match?.[0] || ""; if (results.has(primaryType) || types[primaryType] === void 0) { return results; } results.add(primaryType); for (const field of types[primaryType]) { findTypeDependencies({ primaryType: field.type, types }, results); } return results; } function encodeType({ primaryType, types }) { let result = ""; const unsortedDeps = findTypeDependencies({ primaryType, types }); unsortedDeps.delete(primaryType); const deps = [primaryType, ...Array.from(unsortedDeps).sort()]; for (const type of deps) { result += `${type}(${types[type].map(({ name, type: t }) => `${t} ${name}`).join(",")})`; } return result; } function hashType({ primaryType, types }) { const encodedHashType = toHex(encodeType({ primaryType, types })); return keccak256(encodedHashType); } function encodeData({ data, primaryType, types }) { const encodedTypes = [{ type: "bytes32" }]; const encodedValues = [hashType({ primaryType, types })]; for (const field of types[primaryType]) { const [type, value] = encodeField({ types, name: field.name, type: field.type, value: data[field.name] }); encodedTypes.push(type); encodedValues.push(value); } return encodeAbiParameters(encodedTypes, encodedValues); } function hashStruct({ data, primaryType, types }) { const encoded = encodeData({ data, primaryType, types }); return keccak256(encoded); } function deducePrimaryType(types) { return Object.keys(types)[0]; } function hashTypedData(typedData) { const data = encodeTypedData(typedData); return keccak256(asHex(data)); } function encodeTypedData(typedData) { typedData.primaryType = !typedData?.primaryType ? deducePrimaryType(typedData.types) : typedData?.primaryType; const { domain = {}, message, primaryType } = typedData; const types = { EIP712Domain: getTypesForEIP712Domain({ domain }), ...typedData.types }; validateTypedData({ domain, message, primaryType, types }); const parts = ["0x1901"]; if (domain) parts.push( hashDomain({ domain, types }) ); if (primaryType !== "EIP712Domain") parts.push( hashStruct({ data: message, primaryType, types }) ); return concat(parts); } // src/utils/eip-712/index.ts var EQ_OR_GT_1_3_0 = ">=1.3.0"; var EIP712_DOMAIN_BEFORE_V130 = [ { type: "address", name: "verifyingContract" } ]; var EIP712_DOMAIN = [ { type: "uint256", name: "chainId" }, { type: "address", name: "verifyingContract" } ]; function getEip712TxTypes(safeVersion) { const eip712WithChainId = semverSatisfies(safeVersion, EQ_OR_GT_1_3_0); return { EIP712Domain: eip712WithChainId ? EIP712_DOMAIN : EIP712_DOMAIN_BEFORE_V130, SafeTx: [ { type: "address", name: "to" }, { type: "uint256", name: "value" }, { type: "bytes", name: "data" }, { type: "uint8", name: "operation" }, { type: "uint256", name: "safeTxGas" }, { type: "uint256", name: "baseGas" }, { type: "uint256", name: "gasPrice" }, { type: "address", name: "gasToken" }, { type: "address", name: "refundReceiver" }, { type: "uint256", name: "nonce" } ] }; } function getEip712MessageTypes(safeVersion) { const eip712WithChainId = semverSatisfies(safeVersion, EQ_OR_GT_1_3_0); return { EIP712Domain: eip712WithChainId ? EIP712_DOMAIN : EIP712_DOMAIN_BEFORE_V130, SafeMessage: [{ type: "bytes", name: "message" }] }; } var hashTypedData2 = (typedData) => { return hashTypedData(typedData); }; var hashMessage = (message) => { return performMessageHash(message); }; var hashSafeMessage = (message) => { return typeof message === "string" ? hashMessage(message) : hashTypedData2(message); }; function generateTypedData({ safeAddress, safeVersion, chainId, data }) { const isSafeTransactionDataType = data.hasOwnProperty("to"); const eip712WithChainId = semverSatisfies(safeVersion, EQ_OR_GT_1_3_0); let typedData; if (isSafeTransactionDataType) { const txData = data; typedData = { types: getEip712TxTypes(safeVersion), domain: { verifyingContract: safeAddress }, primaryType: "SafeTx", message: { ...txData, value: txData.value, safeTxGas: txData.safeTxGas, baseGas: txData.baseGas, gasPrice: txData.gasPrice, nonce: txData.nonce } }; } else { const message = data; typedData = { types: getEip712MessageTypes(safeVersion), domain: { verifyingContract: safeAddress }, primaryType: "SafeMessage", message: { message: hashSafeMessage(message) } }; } if (eip712WithChainId) { typedData.domain.chainId = Number(chainId); } return typedData; } // src/utils/safeVersions.ts import semverSatisfies2 from "semver/functions/satisfies.js"; var SAFE_FEATURES_BY_VERSION = { ["SAFE_TX_GAS_OPTIONAL" /* SAFE_TX_GAS_OPTIONAL */]: ">=1.3.0", ["SAFE_TX_GUARDS" /* SAFE_TX_GUARDS */]: ">=1.3.0", ["SAFE_FALLBACK_HANDLER" /* SAFE_FALLBACK_HANDLER */]: ">=1.1.1", ["ETH_SIGN" /* ETH_SIGN */]: ">=1.1.0", ["ACCOUNT_ABSTRACTION" /* ACCOUNT_ABSTRACTION */]: ">=1.3.0", ["REQUIRED_TXGAS" /* REQUIRED_TXGAS */]: "<=1.2.0", ["SIMULATE_AND_REVERT" /* SIMULATE_AND_REVERT */]: ">=1.3.0", ["PASSKEY_SIGNER" /* PASSKEY_SIGNER */]: ">=1.3.0", ["SAFE_L2_CONTRACTS" /* SAFE_L2_CONTRACTS */]: ">=1.3.0", ["SAFE_MODULE_GUARD" /* SAFE_MODULE_GUARD */]: ">=1.5.0" }; var hasSafeFeature = (feature, version) => { if (!(feature in SAFE_FEATURES_BY_VERSION)) { return false; } return semverSatisfies2(version, SAFE_FEATURES_BY_VERSION[feature]); }; // src/utils/signatures/utils.ts import { recoverAddress } from "viem"; import { SigningMethod } from "@safe-global/types-kit"; import semverSatisfies3 from "semver/functions/satisfies.js"; // src/utils/transactions/gas.ts import { BaseError } from "viem"; import { OperationType } from "@safe-global/types-kit"; import semverSatisfies5 from "semver/functions/satisfies.js"; // src/contracts/BaseContract.ts import { encodeFunctionData } from "viem"; import { estimateContractGas, getTransactionReceipt } from "viem/actions"; // src/contracts/config.ts import { getCompatibilityFallbackHandlerDeployments, getCreateCallDeployments, getExtensibleFallbackHandlerDeployments, getMultiSendCallOnlyDeployments, getMultiSendDeployments, getProxyFactoryDeployments, getSafeL2SingletonDeployments, getSafeSingletonDeployments, getSignMessageLibDeployments, getSimulateTxAccessorDeployments } from "@safe-global/safe-deployments"; import { getSafeWebAuthnSignerFactoryDeployment, getSafeWebAuthnShareSignerDeployment } from "@safe-global/safe-modules-deployments"; var DEFAULT_SAFE_VERSION = "1.4.1"; var safeDeploymentsVersions = { "1.5.0": { safeSingletonVersion: "1.5.0", safeSingletonL2Version: "1.5.0", safeProxyFactoryVersion: "1.5.0", compatibilityFallbackHandler: "1.5.0", extensibleFallbackHandler: "1.5.0", multiSendVersion: "1.5.0", multiSendCallOnlyVersion: "1.5.0", signMessageLibVersion: "1.5.0", createCallVersion: "1.5.0", simulateTxAccessorVersion: "1.5.0", safeWebAuthnSignerFactoryVersion: "0.2.1", safeWebAuthnSharedSignerVersion: "0.2.1" }, "1.4.1": { safeSingletonVersion: "1.4.1", safeSingletonL2Version: "1.4.1", safeProxyFactoryVersion: "1.4.1", compatibilityFallbackHandler: "1.4.1", multiSendVersion: "1.4.1", multiSendCallOnlyVersion: "1.4.1", signMessageLibVersion: "1.4.1", createCallVersion: "1.4.1", simulateTxAccessorVersion: "1.4.1", safeWebAuthnSignerFactoryVersion: "0.2.1", safeWebAuthnSharedSignerVersion: "0.2.1" }, "1.3.0": { safeSingletonVersion: "1.3.0", safeSingletonL2Version: "1.3.0", safeProxyFactoryVersion: "1.3.0", compatibilityFallbackHandler: "1.3.0", multiSendVersion: "1.3.0", multiSendCallOnlyVersion: "1.3.0", signMessageLibVersion: "1.3.0", createCallVersion: "1.3.0", simulateTxAccessorVersion: "1.3.0", safeWebAuthnSignerFactoryVersion: "0.2.1", safeWebAuthnSharedSignerVersion: "0.2.1" }, "1.2.0": { safeSingletonVersion: "1.2.0", safeSingletonL2Version: void 0, safeProxyFactoryVersion: "1.1.1", compatibilityFallbackHandler: "1.3.0", multiSendVersion: "1.1.1", multiSendCallOnlyVersion: "1.3.0", signMessageLibVersion: "1.3.0", createCallVersion: "1.3.0", safeWebAuthnSignerFactoryVersion: void 0, safeWebAuthnSharedSignerVersion: void 0 }, "1.1.1": { safeSingletonVersion: "1.1.1", safeSingletonL2Version: void 0, safeProxyFactoryVersion: "1.1.1", compatibilityFallbackHandler: "1.3.0", multiSendVersion: "1.1.1", multiSendCallOnlyVersion: "1.3.0", signMessageLibVersion: "1.3.0", createCallVersion: "1.3.0", safeWebAuthnSignerFactoryVersion: void 0, safeWebAuthnSharedSignerVersion: void 0 }, "1.0.0": { safeSingletonVersion: "1.0.0", safeSingletonL2Version: void 0, safeProxyFactoryVersion: "1.0.0", compatibilityFallbackHandler: "1.3.0", multiSendVersion: "1.1.1", multiSendCallOnlyVersion: "1.3.0", signMessageLibVersion: "1.3.0", createCallVersion: "1.3.0", safeWebAuthnSignerFactoryVersion: void 0, safeWebAuthnSharedSignerVersion: void 0 } }; var safeDeploymentsL1ChainIds = [ 1n // Ethereum Mainnet ]; var contractFunctions = { safeSingletonVersion: getSafeSingletonDeployments, safeSingletonL2Version: getSafeL2SingletonDeployments, safeProxyFactoryVersion: getProxyFactoryDeployments, compatibilityFallbackHandler: getCompatibilityFallbackHandlerDeployments, extensibleFallbackHandler: getExtensibleFallbackHandlerDeployments, multiSendVersion: getMultiSendDeployments, multiSendCallOnlyVersion: getMultiSendCallOnlyDeployments, signMessageLibVersion: getSignMessageLibDeployments, createCallVersion: getCreateCallDeployments, simulateTxAccessorVersion: getSimulateTxAccessorDeployments, safeWebAuthnSignerFactoryVersion: getSafeWebAuthnSignerFactoryDeployment, safeWebAuthnSharedSignerVersion: getSafeWebAuthnShareSignerDeployment }; function getContractDeployment(safeVersion, chainId, contractName3) { const contractVersion = safeDeploymentsVersions[safeVersion][contractName3]; const filters = { version: contractVersion, network: chainId.toString(), released: true }; const deployment = contractFunctions[contractName3](filters); return deployment; } // src/contracts/BaseContract.ts var BaseContract = class { /** * @constructor * Constructs an instance of BaseContract. * * @param contractName - The contract name. * @param chainId - The chain ID of the contract. * @param safeProvider - An instance of SafeProvider. * @param defaultAbi - The default ABI for the contract. It should be compatible with the specific version of the contract. * @param safeVersion - The version of the Safe contract. * @param customContractAddress - Optional custom address for the contract. If not provided, the address is derived from the Safe deployments based on the chainId and safeVersion. * @param customContractAbi - Optional custom ABI for the contract. If not provided, the ABI is derived from the Safe deployments or the defaultAbi is used. * @param deploymentType - Optional deployment type for the contract. If not provided, the first deployment retrieved from the safe-deployments array will be used. */ constructor(contractName3, chainId, safeProvider, defaultAbi, safeVersion, customContractAddress, customContractAbi, deploymentType) { this.getAddress = () => { return this.contractAddress; }; this.encode = (functionToEncode, args) => { const abi = this.contractAbi; const functionName = functionToEncode; const params = args; return encodeFunctionData({ abi, functionName, args: params }); }; this.estimateGas = async (functionToEstimate, args, options = {}) => { const contractOptions = this.convertOptions(options); const abi = this.contractAbi; const params = args; return estimateContractGas(this.runner, { abi, functionName: functionToEstimate, address: this.getAddress(), args: params, ...contractOptions }); }; const deployment = getContractDeployment(safeVersion, chainId, contractName3); const resolvedAddress = customContractAddress ?? this.#resolveAddress( deployment?.networkAddresses[chainId.toString()], deployment, deploymentType ); if (!resolvedAddress) { throw new Error(`Invalid ${contractName3.replace("Version", "")} contract address`); } this.chainId = chainId; this.contractName = contractName3; this.safeVersion = safeVersion; this.contractAddress = resolvedAddress; this.contractAbi = customContractAbi || deployment?.abi || // this cast is required because abi is set as any[] in safe-deployments defaultAbi; this.runner = safeProvider.getExternalProvider(); this.safeProvider = safeProvider; } #resolveAddress(networkAddresses, deployment, deploymentType) { if (!networkAddresses) { return void 0; } if (deploymentType && deployment && "deployments" in deployment) { const customDeploymentTypeAddress = deployment.deployments[deploymentType]?.address; if (typeof networkAddresses === "string") { return networkAddresses === customDeploymentTypeAddress ? customDeploymentTypeAddress : void 0; } return networkAddresses.find((address) => address === customDeploymentTypeAddress); } if (typeof networkAddresses === "string") { return networkAddresses; } return networkAddresses[0]; } async init() { this.wallet = await this.safeProvider.getExternalSigner(); } async getTransactionReceipt(hash) { return getTransactionReceipt(this.runner, { hash }); } /** * Converts a type of TransactionOptions to a viem transaction type. The viem transaction type creates a clear distinction between the multiple transaction objects (e.g., post-London hard fork) and doesn't allow a union of fields. * See: https://github.com/wevm/viem/blob/viem%402.18.0/src/types/fee.ts and https://github.com/wevm/viem/blob/603227e2588366914fb79a902d23fd9afc353cc6/src/types/transaction.ts#L200 * * @param options - Transaction options as expected throughout safe sdk and propagated on the results. * * @returns Options object compatible with Viem */ convertOptions(options) { const chain = this.getChain(); if (!chain) throw new Error("Invalid chainId"); const account = this.getWallet().account; if (!account) throw new Error("Invalid signer"); const txOptions = convertTransactionOptions(options); return { chain, ...txOptions, account }; } getChain() { return getChainById(this.chainId); } getWallet() { if (!this.wallet) throw new Error("A signer must be set"); return this.wallet; } async write(