Skip to content
Merged
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
18 changes: 18 additions & 0 deletions .changeset/swapkit-sdk-jz1qvofrn6a.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
"@swapkit/sdk": patch
"@swapkit/wallet-extensions": patch
"@swapkit/wallet-hardware": patch
"@swapkit/wallet-mobile": patch
"@swapkit/wallets": patch
---

Update SwapKit SDK dependencies:

- @swapkit/core: 4.4.34 → 4.4.37
- @swapkit/helpers: 4.14.0 → 4.14.1
- @swapkit/plugins: 4.6.48 → 4.6.51
- @swapkit/server: 4.3.2 → 4.3.5
- @swapkit/toolboxes: 4.17.2 → 4.17.5
- @swapkit/utxo-signer: 2.2.1 → 2.2.2
- @swapkit/wallet-core: 4.3.5 → 4.3.6
- @swapkit/wallet-keystore: 4.4.2 → 4.4.5
246 changes: 199 additions & 47 deletions bun.lock

Large diffs are not rendered by default.

17 changes: 9 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
"@cosmjs/proto-signing": "0.37.0",
"@cosmjs/stargate": "0.37.0",
"@scure/bip32": "2.2.0",
"@swapkit/core": "^4.4.34",
"@swapkit/helpers": "^4.14.0",
"@swapkit/plugins": "^4.6.48",
"@swapkit/server": "^4.3.2",
"@swapkit/toolboxes": "^4.17.2",
"@swapkit/wallet-core": "^4.3.5",
"@swapkit/wallet-keystore": "^4.4.2",
"@swapkit/core": "^4.4.37",
"@swapkit/helpers": "^4.14.1",
"@swapkit/plugins": "^4.6.51",
"@swapkit/server": "^4.3.5",
"@swapkit/toolboxes": "^4.17.5",
"@swapkit/wallet-core": "^4.3.6",
"@swapkit/wallet-keystore": "^4.4.5",
"@types/bun": "1.3.13",
"@types/node": "25.6.0",
"ledger-bitcoin": "0.3.0",
Expand All @@ -33,6 +33,7 @@
"build:dts": "bun run ./tools/builder/dts.ts",
"announce:release": "bun run ./tools/announce-release.ts",
"changeset": "bunx changeset",
"enrich:dep-changelogs": "bun run ./tools/enrich-dep-changelogs.ts",
"generate:dep-changeset": "bun run ./tools/generate-dep-changeset.ts",
"lint": "bun biome check --fix .",
"lint:ws": "bunx sherif@latest",
Expand All @@ -41,7 +42,7 @@
"test": "bun test",
"type-check": "bun run --filter './packages/*' type-check",
"type-check:ci": "bun run --filter './packages/*' type-check",
"version-bump": "bunx changeset version && bun install"
"version-bump": "bunx changeset version && bun run ./tools/enrich-dep-changelogs.ts && bun install"
},
"workspaces": [
"packages/*",
Expand Down
14 changes: 7 additions & 7 deletions packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
"author": "swapkit-dev",
"dependencies": {
"@stricahq/typhonjs": "~3.0.1",
"@swapkit/core": "^4.4.34",
"@swapkit/helpers": "^4.14.0",
"@swapkit/plugins": "^4.6.48",
"@swapkit/server": "^4.3.2",
"@swapkit/toolboxes": "^4.17.2",
"@swapkit/wallet-core": "^4.3.5",
"@swapkit/wallet-keystore": "^4.4.2",
"@swapkit/core": "^4.4.37",
"@swapkit/helpers": "^4.14.1",
"@swapkit/plugins": "^4.6.51",
"@swapkit/server": "^4.3.5",
"@swapkit/toolboxes": "^4.17.5",
"@swapkit/wallet-core": "^4.3.6",
"@swapkit/wallet-keystore": "^4.4.5",
"@swapkit/wallets": "workspace:*",
"cosmjs-types": "0.10.1"
},
Expand Down
8 changes: 4 additions & 4 deletions packages/wallet-extensions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
"@near-js/transactions": "~2.5.0",
"@scure/base": "~2.2.0",
"@solana/web3.js": "~1.98.4",
"@swapkit/helpers": "^4.14.0",
"@swapkit/toolboxes": "^4.17.2",
"@swapkit/utxo-signer": "^2.2.1",
"@swapkit/wallet-core": "^4.3.5",
"@swapkit/helpers": "^4.14.1",
"@swapkit/toolboxes": "^4.17.5",
"@swapkit/utxo-signer": "^2.2.2",
"@swapkit/wallet-core": "^4.3.6",
"cosmjs-types": "0.10.1",
"ethers": "^6.14.0",
"sats-connect": "~1.0.0",
Expand Down
8 changes: 4 additions & 4 deletions packages/wallet-hardware/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
"@near-js/transactions": "~2.5.0",
"@scure/base": "2.2.0",
"@scure/bip32": "2.2.0",
"@swapkit/helpers": "^4.14.0",
"@swapkit/toolboxes": "^4.17.2",
"@swapkit/utxo-signer": "^2.2.1",
"@swapkit/wallet-core": "^4.3.5",
"@swapkit/helpers": "^4.14.1",
"@swapkit/toolboxes": "^4.17.5",
"@swapkit/utxo-signer": "^2.2.2",
"@swapkit/wallet-core": "^4.3.6",
"@trezor/connect-web": "~9.7.3",
"cosmjs-types": "~0.10.1",
"ethers": "^6.14.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/wallet-mobile/package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"author": "swapkit",
"dependencies": {
"@swapkit/helpers": "^4.14.0",
"@swapkit/toolboxes": "^4.17.2",
"@swapkit/wallet-core": "^4.3.5"
"@swapkit/helpers": "^4.14.1",
"@swapkit/toolboxes": "^4.17.5",
"@swapkit/wallet-core": "^4.3.6"
},
"description": "SwapKit - Wallet Mobile",
"exports": {
Expand Down
8 changes: 4 additions & 4 deletions packages/wallets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
"@radixdlt/radix-dapp-toolkit": "~2.3.0",
"@scure/base": "~2.2.0",
"@scure/bip39": "~2.2.0",
"@swapkit/helpers": "^4.14.0",
"@swapkit/toolboxes": "^4.17.2",
"@swapkit/utxo-signer": "^2.2.1",
"@swapkit/wallet-core": "^4.3.5",
"@swapkit/helpers": "^4.14.1",
"@swapkit/toolboxes": "^4.17.5",
"@swapkit/utxo-signer": "^2.2.2",
"@swapkit/wallet-core": "^4.3.6",
"@swapkit/wallet-extensions": "workspace:*",
"@swapkit/wallet-hardware": "workspace:*",
"@walletconnect/modal": "~2.7.0",
Expand Down
122 changes: 122 additions & 0 deletions tools/enrich-dep-changelogs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// tools/enrich-dep-changelogs.ts
//
// Runs AFTER `changeset version` (wired into `version-bump`), while the Version
// Packages release PR is being built. For every workspace package that bumped in
// THIS release, it finds the `@swapkit/<name>: <old> → <new>` markers that
// generate-dep-changeset wrote, reads each bumped dependency's CHANGELOG from the
// installed packages, slices the (old, new] range, and replaces the markers with
// the REAL underlying changes — so the release PR's changelog shows what actually
// changed, not just which versions moved.
//
// External-dep counterpart of the SDK's packages/builder/src/enrich-changelogs.ts
// (that one resolves internal siblings; this reads @swapkit/* from node_modules).
//
// Wire-up: "version-bump": "bunx changeset version && bun run ./tools/enrich-dep-changelogs.ts && bun install"

import { $, Glob } from "bun";
import { bulletsInRange, changelogCovers, dedupeKey } from "./changelog";

const DRY_RUN = process.argv.includes("--dry-run");
const MAX_BULLETS = 20; // cap a very wide release

// "@swapkit/<name>: <old> → <new>" or "@swapkit/<name>: <new>"
const MARKER = /@swapkit\/([a-z0-9-]+):\s*(?:([\d][\d.]*)\s*→\s*)?([\d][\d.]*)/;

// Version of a package.json at git HEAD (before this `changeset version` run).
async function versionAtHead(pkgJsonPath: string): Promise<string | null> {
try {
const out = await $`git show HEAD:${pkgJsonPath}`.quiet().text();
return (JSON.parse(out) as { version?: string }).version ?? null;
} catch {
return null;
}
}

// An installed copy of the external dep's changelog that covers newVersion. bun's
// isolated layout can hoist a different version to the top level than the one this
// repo uses, so check the hoisted copy first then scan the .bun store.
async function externalChangelog(name: string, newVersion: string): Promise<string | null> {
const hoisted = Bun.file(`node_modules/${name}/CHANGELOG.md`);
if (await hoisted.exists()) {
const text = await hoisted.text();
if (changelogCovers(text, newVersion)) return text;
}
for await (const rel of new Glob(`.bun/*/node_modules/${name}/CHANGELOG.md`).scan({
cwd: "node_modules",
dot: true,
})) {
const text = await Bun.file(`node_modules/${rel}`).text();
if (changelogCovers(text, newVersion)) return text;
}
return null;
}

// --- Main ---------------------------------------------------------------------
for await (const file of new Glob("*/CHANGELOG.md").scan("./packages")) {
const path = `./packages/${file}`;
const pkgJsonPath = path.replace(/CHANGELOG\.md$/, "package.json");

// Only packages that actually bumped in this `changeset version` run.
const current = ((await Bun.file(pkgJsonPath).json()) as { version?: string }).version;
const head = await versionAtHead(pkgJsonPath.replace(/^\.\//, ""));
if (!current || current === head) continue;

const lines = (await Bun.file(path).text()).split("\n");

// Newest (top) section bounds.
const start = lines.findIndex((l) => /^## /.test(l));
if (start < 0) continue;
let end = lines.findIndex((l, i) => i > start && /^## /.test(l));
if (end < 0) end = lines.length;

// Marker lines within the newest section.
const markerIdx: number[] = [];
const refs: { name: string; old: string; new: string }[] = [];
for (let i = start; i < end; i++) {
const m = lines[i]?.match(MARKER);
if (m?.[1] && m[3]) {
markerIdx.push(i);
refs.push({ name: `@swapkit/${m[1]}`, new: m[3], old: m[2] ?? "" });
}
}
if (refs.length === 0) continue;

// Resolve the underlying changes for each bumped dep, deduped across deps.
const seen = new Set<string>();
const enriched: string[] = [];
for (const ref of refs) {
const changelog = await externalChangelog(ref.name, ref.new);
if (!changelog) {
console.warn(`⚠ no installed CHANGELOG covering ${ref.name}@${ref.new} — leaving its marker as-is`);
enriched.push(` - ${ref.name}: ${ref.old ? `${ref.old} → ${ref.new}` : ref.new}`);
continue;
}
// Keep each bullet verbatim — the SDK changelogs are already enriched and
// carry their own accurate "(via @swapkit/x@y)" attribution. Dedupe across
// deps by commit hash (the same change appears in several cumulative changelogs).
for (const bullet of bulletsInRange(changelog, ref.old, ref.new)) {
const key = dedupeKey(bullet);
if (seen.has(key)) continue;
seen.add(key);
enriched.push(` - ${bullet.replace(/^- /, "")}`);
}
}
if (enriched.length === 0) continue;

const kept = enriched.slice(0, MAX_BULLETS);
const overflow = enriched.length - kept.length;
if (overflow > 0) kept.push(` - …and ${overflow} more dependency change${overflow > 1 ? "s" : ""}`);

// Replace the contiguous marker block with the enriched bullets, keeping the
// intro line (the bullet above the first marker) intact.
const first = markerIdx[0] as number;
const last = markerIdx[markerIdx.length - 1] as number;
const rebuilt = [...lines.slice(0, first), ...kept, ...lines.slice(last + 1)].join("\n");

if (DRY_RUN) {
console.info(`\n=== ${file.split("/")[0]} @ ${current} ===\n${kept.join("\n")}`);
} else {
await Bun.write(path, rebuilt);
console.info(`✅ enriched ${file.split("/")[0]}@${current} (${kept.length} change notes)`);
}
}
90 changes: 20 additions & 70 deletions tools/generate-dep-changeset.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,26 @@
// tools/generate-dep-changeset.ts
//
// Generates a RICH changeset describing the real SwapKit SDK changes pulled in by
// an @swapkit/* dependency bump. It diffs the external @swapkit/* dep versions in
// this branch against a base ref, reads the (already-enriched) SDK CHANGELOGs for
// each bumped range, and writes one changeset listing the actual changes —
// instead of a generic "deps got bumped".
// Emits a SIMPLE, deterministic changeset when external @swapkit/* dependency
// versions change vs a base ref. It diffs the versions and records each bumped
// dep as an `old → new` marker — it does NOT read any changelog here.
//
// Changelog source: the SDK ships CHANGELOG.md inside the published npm tarball
// (swapkit/sdk #274), so after `bun install` the installed (new) version's
// cumulative changelog is on disk and already covers the whole (old, new] range.
// We read it straight from node_modules — no token, no network. If a bumped
// version predates the in-package changelog (so it isn't on disk), that bump
// falls back to a generic "Update SwapKit SDK dependencies" line.
// The real underlying changes are inlined later, at release time, by
// tools/enrich-dep-changelogs.ts (run from `version-bump`, after
// `changeset version`), which reads the bumped deps' changelogs from the
// installed packages. Keeping this step changelog-free makes it deterministic
// (no node_modules dependency, no network) so the enforce-dep-changeset CI check
// can regenerate-and-compare reliably.
//
// Bump-path-agnostic: works for the dispatch auto-update, the scheduled update,
// and a human manually editing package.json. Deterministic output (no timestamps)
// so a CI check can regenerate-and-compare to enforce it. Run `bun install`
// before this script so the installed changelogs are present.
// and a human manually editing package.json.
//
// Env:
// BASE_REF git ref to diff dep versions against (default: origin/develop)
// SDK_REPO_PATH local SDK checkout — read files from disk (testing only)
// BASE_REF git ref to diff dep versions against (default: origin/develop)

import { $, Glob } from "bun";
import { bulletsInRange, changelogCovers, dedupeKey, stripViaSuffix } from "./changelog";

const DRY_RUN = process.argv.includes("--dry-run");
const BASE_REF = process.env.BASE_REF || "origin/develop";
const SDK_REPO_PATH = process.env.SDK_REPO_PATH;

const DEP_FIELDS = ["dependencies", "devDependencies", "peerDependencies"] as const;
type Json = { name?: string } & Partial<Record<(typeof DEP_FIELDS)[number], Record<string, string>>>;
Expand All @@ -53,28 +46,6 @@ async function gitShow(ref: string, path: string): Promise<string | null> {
}
}

async function sdkChangelog(name: string, newVersion: string): Promise<string | null> {
const dir = name.replace("@swapkit/", "");

// Local SDK checkout — testing only.
if (SDK_REPO_PATH) {
const file = Bun.file(`${SDK_REPO_PATH}/packages/${dir}/CHANGELOG.md`);
return (await file.exists()) ? file.text() : null;
}

// The installed package's own changelog (no token, no network). The new
// version's changelog is cumulative, so it covers the full (old, new] range.
// Only trust it if it actually has the version we bumped to — otherwise
// node_modules is stale, install didn't run, or the version predates the
// in-package changelog; in all those cases we degrade to a generic line.
const installed = Bun.file(`node_modules/${name}/CHANGELOG.md`);
if (await installed.exists()) {
const text = await installed.text();
if (changelogCovers(text, newVersion)) return text;
}
return null;
}

// --- Main ---------------------------------------------------------------------
const pkgFiles: string[] = [];
const workspace = new Set<string>();
Expand All @@ -101,28 +72,7 @@ if (changed.size === 0) {
process.exit(0);
}

// 2. Slice the SDK changelogs for each bumped range, aggregate + dedupe bullets.
const seen = new Set<string>();
const bullets: string[] = [];
for (const [name, { old, new: newV }] of [...changed].sort(([a], [b]) => a.localeCompare(b))) {
const changelog = await sdkChangelog(name, newV);
if (!changelog) {
console.warn(`⚠ no in-package CHANGELOG for ${name}@${newV} — it will fall back to a generic line`);
continue;
}
for (const bullet of bulletsInRange(changelog, old, newV)) {
// The same change shows up both in its origin package's changelog and in a
// dependent's enriched changelog (suffixed `(via @swapkit/x@y)`). Dedupe on
// the commit hash (stable across both), then PR number, then text; and drop
// the `(via …)` annotation so the kept line reads cleanly.
const key = dedupeKey(bullet);
if (seen.has(key)) continue;
seen.add(key);
bullets.push(stripViaSuffix(bullet));
}
}

// 3. Which of THIS repo's packages depend on a changed dep → patch bump.
// 2. Which of THIS repo's packages depend on a changed dep → patch bump.
const bumps = new Set<string>();
for (const f of pkgFiles) {
const json = (await Bun.file(f).json()) as Json;
Expand All @@ -136,22 +86,22 @@ if (bumps.size === 0) {
process.exit(0);
}

// 4. Build the changeset (deterministic filename from the bumped versions).
const summary = [...changed].sort(([a], [b]) => a.localeCompare(b)).map(([n, v]) => `${n}@${v.new}`);
const id = `swapkit-sdk-${Bun.hash(summary.join(",")).toString(36)}`;
// 3. Build the changeset: one `old → new` marker per bumped dep. The release-time
// enricher (tools/enrich-dep-changelogs.ts) parses these markers and replaces
// them with the real underlying changes. Deterministic filename from the bumps.
const sorted = [...changed].sort(([a], [b]) => a.localeCompare(b));
const id = `swapkit-sdk-${Bun.hash(sorted.map(([n, v]) => `${n}@${v.new}`).join(",")).toString(36)}`;
const frontmatter = [...bumps]
.sort()
.map((n) => `"${n}": patch`)
.join("\n");
const body =
bullets.length > 0
? ["Update SwapKit SDK dependencies. Underlying changes:", "", ...bullets].join("\n")
: `Update SwapKit SDK dependencies: ${summary.join(", ")}.`;
const markers = sorted.map(([n, v]) => `- ${n}: ${v.old ? `${v.old} → ${v.new}` : v.new}`);
const body = ["Update SwapKit SDK dependencies:", "", ...markers].join("\n");
const content = `---\n${frontmatter}\n---\n\n${body}\n`;

if (DRY_RUN) {
console.info(`# .changeset/${id}.md\n\n${content}`);
} else {
await Bun.write(`.changeset/${id}.md`, content);
console.info(`📝 wrote .changeset/${id}.md (${bumps.size} packages, ${bullets.length} change notes)`);
console.info(`📝 wrote .changeset/${id}.md (${bumps.size} packages, ${changed.size} deps)`);
}
Loading