Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions packages/core/src/contracts/resolve-method-args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { CaatingaError, CaatingaErrorCode } from "../errors/CaatingaError.js";
import { formatNamedCliArgs } from "./format-cli-args.js";
import { resolveSourceAddress } from "./resolve-source-address.js";
import type { DeployArgValue } from "./resolve-deploy-args.js";

const STELLAR_ADDRESS_REGEX = /^G[A-Z2-7]{55}$/;
import { STELLAR_ADDRESS_REGEX } from "../stellar-cli/strkey.js";

export type ResolveMethodArgsOptions = {
args: Record<string, DeployArgValue>;
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/contracts/resolve-source-address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { CaatingaError, CaatingaErrorCode } from "../errors/CaatingaError.js";
import { checkBinary } from "../shell/check-binary.js";
import { runCommand } from "../shell/run-command.js";
import { assertSafeSourceAccount } from "./source-account.js";

const STELLAR_ADDRESS_REGEX = /^G[A-Z2-7]{55}$/;
import { STELLAR_ADDRESS_REGEX } from "../stellar-cli/strkey.js";

export async function resolveSourceAddress(options: {
source: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/contracts/validate-source-shape.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CaatingaError, CaatingaErrorCode } from "../errors/CaatingaError.js";
import { isLikelyPublicKeySource } from "../stellar-cli/recover-deploy-contract-id.js";
import { isLikelyPublicKeySource } from "../stellar-cli/strkey.js";

export function validateSourceShape(source: string): CaatingaError | undefined {
if (source.startsWith("S")) {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/stellar-cli/recover-deploy-contract-id.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ type HorizonOperationsResponse = {
};
};

export function isLikelyPublicKeySource(source: string): boolean {
return /^G[A-Z2-7]{55}$/.test(source);
}
// Re-exported from the shared strkey module (#148); kept here for back-compat
// with existing importers of this path.
export { isLikelyPublicKeySource } from "./strkey.js";

export function decimalSaltToHex(salt: string): string {
return BigInt(salt).toString(16).padStart(64, "0");
Expand Down
19 changes: 19 additions & 0 deletions packages/core/src/stellar-cli/strkey.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { describe, expect, it } from "vitest";
import { STELLAR_ADDRESS_REGEX, isLikelyPublicKeySource } from "./strkey.js";

describe("strkey", () => {
const validKey = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF";

it("should_match_a_valid_public_key", () => {
expect(STELLAR_ADDRESS_REGEX.test(validKey)).toBe(true);
expect(isLikelyPublicKeySource(validKey)).toBe(true);
});

it("should_reject_named_aliases_and_malformed_keys", () => {
expect(isLikelyPublicKeySource("alice")).toBe(false);
expect(isLikelyPublicKeySource(validKey.slice(0, -1))).toBe(false); // too short
expect(isLikelyPublicKeySource(`${validKey}A`)).toBe(false); // too long
expect(isLikelyPublicKeySource(validKey.replace("G", "M"))).toBe(false); // wrong version byte
expect(isLikelyPublicKeySource(validKey.replace(/.$/, "1"))).toBe(false); // 1 not in base32 alphabet
});
});
13 changes: 13 additions & 0 deletions packages/core/src/stellar-cli/strkey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Single source of truth for the Stellar account (public-key) strkey shape.
// Previously this regex was copy-pasted in three places (resolve-method-args,
// resolve-source-address, recover-deploy-contract-id) and source validation
// reached into the deploy-recovery module just to borrow it (#148). Centralizing
// it here removes the divergence risk and the cross-module coupling.

/** Stellar account (public-key) strkey: `G` followed by 55 base32 `[A-Z2-7]` chars. */
export const STELLAR_ADDRESS_REGEX = /^G[A-Z2-7]{55}$/;

/** True when `source` is a raw Stellar public key rather than a named alias. */
export function isLikelyPublicKeySource(source: string): boolean {
return STELLAR_ADDRESS_REGEX.test(source);
}