diff --git a/src/app/(sidebar)/transaction/dashboard/components/Signatures.tsx b/src/app/(sidebar)/transaction/dashboard/components/Signatures.tsx
index 8da474f3c..2e6a2da69 100644
--- a/src/app/(sidebar)/transaction/dashboard/components/Signatures.tsx
+++ b/src/app/(sidebar)/transaction/dashboard/components/Signatures.tsx
@@ -1,4 +1,10 @@
-import { StrKey, TransactionBuilder } from "@stellar/stellar-sdk";
+import {
+ hash,
+ Keypair,
+ StrKey,
+ TransactionBuilder,
+ xdr,
+} from "@stellar/stellar-sdk";
import { Icon, Link, Text } from "@stellar/design-system";
import { useStore } from "@/store/useStore";
@@ -103,7 +109,14 @@ export const Signatures = ({
const renderAuthEntriesTableBody = () => {
return authEntries.map((entry, index) => {
const rowKey = `auth-entry-row-${index}`;
- const isMatch = verifyAuthEntryPublicKey(entry.publicKey, entry.address);
+ const isMatch =
+ isXdrInit &&
+ verifyAuthEntrySignature(
+ entry.rawEntry,
+ entry.publicKey,
+ entry.signature,
+ network.passphrase,
+ );
return (
@@ -244,17 +257,55 @@ const renderSigner = (isVerified: boolean, signer: string) => {
};
/**
- * Verifies that the public key bytes in an auth entry signature match the
- * credential address (G... key).
+ * Verifies a Soroban authorization entry signature cryptographically.
+ *
+ * Reconstructs the HashIdPreimage (network ID, nonce, invocation,
+ * signatureExpirationLedger), hashes it, and verifies the Ed25519 signature.
+ *
+ * @param rawEntry - The JSON-decoded SorobanAuthorizationEntry
+ * @param publicKeyHex - The hex-encoded public key from the signature map
+ * @param signatureHex - The hex-encoded signature bytes from the signature map
+ * @param networkPassphrase - The network passphrase (e.g. "Test SDF Network ; September 2015")
+ * @returns true if the signature is cryptographically valid
+ *
+ * @example
+ * const isValid = verifyAuthEntrySignature(entry.rawEntry, entry.publicKey, entry.signature, network.passphrase);
*/
-const verifyAuthEntryPublicKey = (
+const verifyAuthEntrySignature = (
+ rawEntry: any,
publicKeyHex: string,
- address: string,
+ signatureHex: string,
+ networkPassphrase: string,
): boolean => {
try {
- const publicKeyBytes = Buffer.from(publicKeyHex, "hex");
- const derivedAddress = StrKey.encodeEd25519PublicKey(publicKeyBytes);
- return derivedAddress === address;
+ const entryXdrBase64 = StellarXdr.encode(
+ "SorobanAuthorizationEntry",
+ JSON.stringify(rawEntry),
+ );
+ const authEntry = xdr.SorobanAuthorizationEntry.fromXDR(
+ entryXdrBase64,
+ "base64",
+ );
+
+ const addrAuth = authEntry.credentials().address();
+ const networkId = hash(Buffer.from(networkPassphrase));
+
+ const preimage = xdr.HashIdPreimage.envelopeTypeSorobanAuthorization(
+ new xdr.HashIdPreimageSorobanAuthorization({
+ networkId,
+ nonce: addrAuth.nonce(),
+ invocation: authEntry.rootInvocation(),
+ signatureExpirationLedger: addrAuth.signatureExpirationLedger(),
+ }),
+ );
+
+ const payload = hash(preimage.toXDR());
+ const stellarAddress = StrKey.encodeEd25519PublicKey(
+ Buffer.from(publicKeyHex, "hex"),
+ );
+ const keypair = Keypair.fromPublicKey(stellarAddress);
+
+ return keypair.verify(payload, Buffer.from(signatureHex, "hex"));
} catch {
return false;
}
@@ -266,6 +317,7 @@ type AuthEntryInfo = {
publicKey: string;
signature: string;
contractId: string;
+ rawEntry: any;
};
const getAuthEntries = (operations: any[] | undefined): AuthEntryInfo[] => {
@@ -305,6 +357,7 @@ const parseAuthEntry = (authEntry: any): AuthEntryInfo | null => {
publicKey,
signature,
contractId: contractFn ? contractFn.contract_address : "-",
+ rawEntry: authEntry,
};
};
diff --git a/src/constants/networkLimits.ts b/src/constants/networkLimits.ts
index 2d35f352c..629c8ccc0 100644
--- a/src/constants/networkLimits.ts
+++ b/src/constants/networkLimits.ts
@@ -83,36 +83,36 @@ export const MAINNET_LIMITS: NetworkLimits = {
"persistent_rent_rate_denominator": "1215",
"temp_rent_rate_denominator": "2430",
"live_soroban_state_size_window": [
- "698933560",
- "699854984",
- "700498804",
- "700342140",
- "700482104",
- "700881920",
- "701866036",
- "702327232",
- "702236112",
- "702418272",
- "702794004",
- "703655676",
- "703906824",
- "704134152",
- "704376184",
- "704566128",
- "704783500",
- "705684296",
- "706367628",
- "706533156",
- "706697884",
- "706985136",
- "707803656",
- "707819944",
- "707582232",
- "708142500",
- "708686816",
- "709541828",
- "710004992",
- "709889972"
+ "815655900",
+ "816156784",
+ "816421916",
+ "816448200",
+ "816688596",
+ "817658144",
+ "818086792",
+ "818199320",
+ "818175708",
+ "818472788",
+ "818694368",
+ "819311776",
+ "819455068",
+ "819547528",
+ "819953300",
+ "820403320",
+ "820785516",
+ "820958412",
+ "821015980",
+ "821398448",
+ "822010672",
+ "822249580",
+ "822400856",
+ "822483696",
+ "822863824",
+ "823466952",
+ "824503299",
+ "824704343",
+ "824784835",
+ "825149423"
],
"state_target_size_bytes": "3000000000",
"rent_fee_1kb_state_size_low": "-17000",
@@ -151,36 +151,36 @@ export const TESTNET_LIMITS: NetworkLimits = {
"persistent_rent_rate_denominator": "1215",
"temp_rent_rate_denominator": "2430",
"live_soroban_state_size_window": [
- "1056094012",
- "1056110820",
- "1056122744",
- "1056144036",
- "1056165652",
- "1056199296",
- "1056237568",
- "1056111820",
- "1056132616",
- "1054811063",
- "1051914996",
- "1051938276",
- "1051964392",
- "1051990536",
- "1052023580",
- "1052055240",
- "1052077332",
- "1052101084",
- "1052119060",
- "1052135908",
- "1052154432",
- "1052174020",
- "1052179092",
- "1052185260",
- "1052189220",
- "1052192112",
- "1052195920",
- "1052050520",
- "1052052120",
- "1051275947"
+ "1240242453",
+ "1240326850",
+ "1240656940",
+ "1240689812",
+ "1240708488",
+ "1240729856",
+ "1240967315",
+ "1240976667",
+ "1240983511",
+ "1240169291",
+ "1239755754",
+ "1240718349",
+ "1244432760",
+ "1245077948",
+ "1245080420",
+ "1245109817",
+ "1247727563",
+ "1247742799",
+ "1247622811",
+ "1247537883",
+ "1244542212",
+ "1243128094",
+ "1243133610",
+ "1243133598",
+ "1243139894",
+ "1243164614",
+ "1243186802",
+ "1243193614",
+ "1243195062",
+ "1241090546"
],
"state_target_size_bytes": "3000000000",
"rent_fee_1kb_state_size_low": "-17000",
@@ -219,36 +219,36 @@ export const FUTURENET_LIMITS: NetworkLimits = {
"persistent_rent_rate_denominator": "1215",
"temp_rent_rate_denominator": "2430",
"live_soroban_state_size_window": [
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71567703",
- "71566291",
- "71566291",
- "71566291",
- "71566291",
- "71566291",
- "71566291",
- "71566291",
- "71566291",
- "71566291",
- "71566291",
- "71566291",
- "71566291",
- "71566291"
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013",
+ "69864013"
],
"state_target_size_bytes": "3000000000",
"rent_fee_1kb_state_size_low": "-17000",
@@ -2503,18 +2503,18 @@ export const FUTURENET_LIMITS_JSON: NetworkLimitsJson = {
},
{
"ext": "v0",
- "const_term": "2426722",
- "linear_term": "96397671"
+ "const_term": "2347584",
+ "linear_term": "94135478"
},
{
"ext": "v0",
- "const_term": "1541554",
+ "const_term": "1020885",
"linear_term": "0"
},
{
"ext": "v0",
- "const_term": "3211191",
- "linear_term": "6713"
+ "const_term": "2638451",
+ "linear_term": "6803"
},
{
"ext": "v0",
@@ -2528,18 +2528,18 @@ export const FUTURENET_LIMITS_JSON: NetworkLimitsJson = {
},
{
"ext": "v0",
- "const_term": "8035968",
- "linear_term": "309667335"
+ "const_term": "7663880",
+ "linear_term": "298580871"
},
{
"ext": "v0",
- "const_term": "2420202",
+ "const_term": "1856539",
"linear_term": "0"
},
{
"ext": "v0",
- "const_term": "7050564",
- "linear_term": "6797"
+ "const_term": "6315452",
+ "linear_term": "7232"
},
{
"ext": "v0",
@@ -2598,7 +2598,7 @@ export const FUTURENET_LIMITS_JSON: NetworkLimitsJson = {
},
{
"ext": "v0",
- "const_term": "2937755",
+ "const_term": "1706052",
"linear_term": "0"
},
{
@@ -2650,6 +2650,11 @@ export const FUTURENET_LIMITS_JSON: NetworkLimitsJson = {
"ext": "v0",
"const_term": "33151",
"linear_term": "0"
+ },
+ {
+ "ext": "v0",
+ "const_term": "1185193",
+ "linear_term": "41568084"
}
]
},
@@ -2933,16 +2938,16 @@ export const FUTURENET_LIMITS_JSON: NetworkLimitsJson = {
{
"ext": "v0",
"const_term": "109494",
- "linear_term": "354667"
+ "linear_term": "266603"
},
{
"ext": "v0",
- "const_term": "5552",
+ "const_term": "2776",
"linear_term": "0"
},
{
"ext": "v0",
- "const_term": "9424",
+ "const_term": "5896",
"linear_term": "0"
},
{
@@ -2958,16 +2963,16 @@ export const FUTURENET_LIMITS_JSON: NetworkLimitsJson = {
{
"ext": "v0",
"const_term": "219654",
- "linear_term": "354667"
+ "linear_term": "266603"
},
{
"ext": "v0",
- "const_term": "3344",
+ "const_term": "1672",
"linear_term": "0"
},
{
"ext": "v0",
- "const_term": "6816",
+ "const_term": "3960",
"linear_term": "0"
},
{
@@ -3079,6 +3084,11 @@ export const FUTURENET_LIMITS_JSON: NetworkLimitsJson = {
"ext": "v0",
"const_term": "0",
"linear_term": "0"
+ },
+ {
+ "ext": "v0",
+ "const_term": "73061",
+ "linear_term": "229779"
}
]
},