Skip to content

Commit e9a74ea

Browse files
committed
merge: resolve conflicts with leojay-net/main for PR #1316
Resolution strategy: - UD (modify/delete): accepted upstream deletions for files moved to Dechat/ by leojay-net/main - AA (add/add): kept theirs for useIdempotentAction.ts/.test.ts (complete implementation) - AU: staged BankDetailsModal.memory-leak.test.tsx in its Dechat/ path - UU Dechat/ files: took leojay-net/main (theirs) — docs-and-core did not modify these implementation files; conflicts were residual from prior merges - Covered: AuditTable, CCIPBridgeModal, ChatMessages, Message, StellarFiatModal, ToastProvider, UserPreferencesContext, useFeatureFlag, useSplitView, useTransactionFilters, cryptoPriceService, rateLimit.test, stellar-contracts
2 parents 2f344b2 + 2d76b71 commit e9a74ea

2,195 files changed

Lines changed: 1737650 additions & 32231 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.devcontainer/devcontainer.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "Stellar Dex Chat",
3+
"image": "mcr.microsoft.com/devcontainers/rust:1-bullseye",
4+
"features": {
5+
"ghcr.io/devcontainers/features/node:1": {
6+
"version": "20"
7+
}
8+
},
9+
"postCreateCommand": "bash .devcontainer/post-create.sh",
10+
"customizations": {
11+
"vscode": {
12+
"extensions": [
13+
"rust-lang.rust-analyzer",
14+
"tamasfe.even-better-toml",
15+
"esbenp.prettier-vscode",
16+
"dbaeumer.vscode-eslint",
17+
"ms-playwright.playwright"
18+
],
19+
"settings": {
20+
"rust-analyzer.cargo.target": "wasm32-unknown-unknown",
21+
"editor.formatOnSave": true,
22+
"editor.defaultFormatter": "esbenp.prettier-vscode",
23+
"[rust]": {
24+
"editor.defaultFormatter": "rust-lang.rust-analyzer"
25+
}
26+
}
27+
}
28+
},
29+
"remoteEnv": {
30+
"SOROBAN_NETWORK": "testnet",
31+
"SOROBAN_RPC_URL": "https://soroban-testnet.stellar.org"
32+
}
33+
}

.devcontainer/post-create.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
echo "==> Adding wasm32 target for Soroban contract builds"
5+
rustup target add wasm32-unknown-unknown
6+
7+
echo "==> Installing stellar-cli"
8+
cargo install --locked stellar-cli --features opt
9+
10+
echo "==> Installing pnpm"
11+
npm install -g pnpm
12+
13+
echo "==> Installing frontend dependencies"
14+
cd Dechat/dex_with_fiat_frontend
15+
pnpm install
16+
pnpm test:e2e:install
17+
cd ../..
18+
19+
echo "==> Dev environment ready. Run 'stellar --version' to verify."

.github/dependabot.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "cargo"
4+
directory: "/Dechat/stellar-contracts"
5+
schedule:
6+
interval: "weekly"
7+
8+
- package-ecosystem: "npm"
9+
directory: "/Dechat/dex_with_fiat_frontend"
10+
schedule:
11+
interval: "weekly"
12+
13+
- package-ecosystem: "github-actions"
14+
directory: "/"
15+
schedule:
16+
interval: "weekly"

.github/workflows/auto-merge.yml

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: Auto-Merge PRs
22

3+
<<<<<<< HEAD
34
# Fires when a PR is opened/updated (to enable native auto-merge) and when a
45
# check suite completes (to directly merge if every check went green and the
56
# branch has no conflicts).
@@ -125,5 +126,177 @@ jobs:
125126
core.info(`✅ Auto-merged PR #${pr.number}: ${pull.title}`);
126127
} catch (err) {
127128
core.error(`Failed to merge PR #${pr.number}: ${err.message}`);
129+
=======
130+
# Merges open PRs once every check that ran for their head commit has gone green.
131+
#
132+
# Why `workflow_run` and not `check_suite`:
133+
# GitHub does not start a new workflow run from events generated by the
134+
# built-in GITHUB_TOKEN, so the `check_suite: completed` suites produced by
135+
# Actions never triggered this workflow (0 runs in ~40 attempts). `workflow_run`
136+
# is the supported way to react to another workflow finishing.
137+
#
138+
# Why not GitHub's native auto-merge (`gh pr merge --auto`):
139+
# `main` has no branch protection and therefore no *required* status checks.
140+
# Native auto-merge only waits for required checks, so with none configured it
141+
# merges as soon as the PR is mergeable — i.e. before CI has finished. This
142+
# workflow evaluates the checks itself instead.
143+
#
144+
# Security: jobs here run in the base-repo context with a writable token and
145+
# deliberately never check out or execute PR-authored code — they only call the
146+
# REST API.
147+
148+
on:
149+
workflow_run:
150+
workflows:
151+
- "Frontend CI"
152+
- "Frontend Build Check"
153+
- "Smart Contract CI"
154+
- "Contract Tests"
155+
types: [completed]
156+
# Safety net: re-sweep periodically so a PR whose triggering event was missed
157+
# (or that went green while another PR was merging) still lands.
158+
schedule:
159+
- cron: "*/30 * * * *"
160+
workflow_dispatch:
161+
162+
permissions:
163+
contents: write # needed to merge
164+
pull-requests: write # needed to comment / update PRs
165+
checks: read
166+
statuses: read
167+
168+
concurrency:
169+
group: auto-merge
170+
cancel-in-progress: false
171+
172+
jobs:
173+
merge-green-prs:
174+
name: Merge PRs with all checks passing
175+
runs-on: ubuntu-latest
176+
steps:
177+
- name: Evaluate and merge
178+
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
179+
with:
180+
github-token: ${{ secrets.GITHUB_TOKEN }}
181+
script: |
182+
const { owner, repo } = context.repo;
183+
const TERMINAL_OK = ['success', 'skipped', 'neutral'];
184+
185+
// ── Work out which PRs to consider ────────────────────────────
186+
// `workflow_run.pull_requests` is always empty for PRs from forks,
187+
// so resolve candidates by matching head SHA against open PRs.
188+
const openPrs = await github.paginate(github.rest.pulls.list, {
189+
owner, repo, state: 'open', per_page: 100,
190+
});
191+
192+
let candidates = openPrs;
193+
if (context.eventName === 'workflow_run') {
194+
const run = context.payload.workflow_run;
195+
if (run.conclusion !== 'success') {
196+
core.info(`Upstream run "${run.name}" concluded "${run.conclusion}" — nothing to do.`);
197+
return;
198+
}
199+
candidates = openPrs.filter(pr => pr.head.sha === run.head_sha);
200+
if (candidates.length === 0) {
201+
core.info(`No open PR matches head SHA ${run.head_sha}.`);
202+
return;
203+
}
204+
}
205+
206+
core.info(`Evaluating ${candidates.length} PR(s).`);
207+
208+
for (const summary of candidates) {
209+
const number = summary.number;
210+
211+
// Re-fetch: the list payload omits `mergeable`/`mergeable_state`.
212+
let { data: pr } = await github.rest.pulls.get({
213+
owner, repo, pull_number: number,
214+
});
215+
216+
if (pr.draft) { core.info(`#${number}: draft — skipping.`); continue; }
217+
if (pr.state !== 'open') { core.info(`#${number}: not open — skipping.`); continue; }
218+
219+
// ── Checks must all be finished and green ───────────────────
220+
const sha = pr.head.sha;
221+
const { data: { check_runs } } = await github.rest.checks.listForRef({
222+
owner, repo, ref: sha, per_page: 100,
223+
});
224+
225+
// Ignore this workflow's own check so it never waits on itself.
226+
const relevant = check_runs.filter(r => r.name !== 'Merge PRs with all checks passing');
227+
228+
if (relevant.length === 0) {
229+
core.info(`#${number}: no checks reported for ${sha} — refusing to merge unchecked.`);
230+
continue;
231+
}
232+
233+
const pending = relevant.filter(r => r.status !== 'completed');
234+
if (pending.length > 0) {
235+
core.info(`#${number}: still running (${pending.map(r => r.name).join(', ')}) — waiting.`);
236+
continue;
237+
}
238+
239+
const failing = relevant.filter(r => !TERMINAL_OK.includes(r.conclusion));
240+
if (failing.length > 0) {
241+
core.info(`#${number}: failing checks (${failing.map(r => r.name).join(', ')}) — skipping.`);
242+
continue;
243+
}
244+
245+
// Legacy commit statuses (non-Actions integrations) count too.
246+
const { data: combined } = await github.rest.repos.getCombinedStatusForRef({
247+
owner, repo, ref: sha,
248+
});
249+
if (combined.total_count > 0 && combined.state !== 'success') {
250+
core.info(`#${number}: commit status is "${combined.state}" — skipping.`);
251+
continue;
252+
}
253+
254+
// ── Mergeability (computed asynchronously by GitHub) ────────
255+
for (let attempt = 0; pr.mergeable === null && attempt < 3; attempt++) {
256+
core.info(`#${number}: mergeability not computed yet, retrying in 5s…`);
257+
await new Promise(r => setTimeout(r, 5000));
258+
({ data: pr } = await github.rest.pulls.get({
259+
owner, repo, pull_number: number,
260+
}));
261+
}
262+
263+
if (pr.mergeable === false) {
264+
core.info(`#${number}: merge conflicts (${pr.mergeable_state}) — skipping.`);
265+
continue;
266+
}
267+
if (pr.mergeable === null) {
268+
core.info(`#${number}: mergeability still unknown — will retry next sweep.`);
269+
continue;
270+
}
271+
if (['blocked', 'behind', 'draft'].includes(pr.mergeable_state)) {
272+
core.info(`#${number}: mergeable_state="${pr.mergeable_state}" — skipping.`);
273+
continue;
274+
}
275+
276+
// ── Merge ──────────────────────────────────────────────────
277+
// Drop AI-assistant co-author trailers from the squash message.
278+
// Human co-authors are deliberately left intact — stripping those
279+
// would erase real contributor attribution.
280+
const body = (pr.body ?? '')
281+
.split('\n')
282+
.filter(line => !/^\s*co-authored-by:.*(claude|anthropic\.com)/i.test(line))
283+
.join('\n')
284+
.trim();
285+
286+
try {
287+
await github.rest.pulls.merge({
288+
owner, repo,
289+
pull_number: number,
290+
merge_method: 'squash',
291+
commit_title: `${pr.title} (#${number})`,
292+
commit_message: body,
293+
sha,
294+
});
295+
core.notice(`Auto-merged #${number}: ${pr.title}`);
296+
} catch (err) {
297+
// 405 = not mergeable right now, 409 = head moved. Both are
298+
// transient; the next sweep retries.
299+
core.warning(`#${number}: merge failed (${err.status}): ${err.message}`);
300+
>>>>>>> emwulrd/main
128301
}
129302
}

.github/workflows/changelog.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616

1717
steps:
1818
- name: Checkout repository
19+
<<<<<<< HEAD
1920
uses: actions/checkout@v4
2021
with:
2122
fetch-depth: 0
@@ -28,6 +29,39 @@ jobs:
2829

2930
- name: Commit and push CHANGELOG.md
3031
uses: stefanzweifel/git-auto-commit-action@v5
32+
=======
33+
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
34+
with:
35+
fetch-depth: 0
36+
37+
# Run the binary directly rather than orhun/git-cliff-action. The action
38+
# marshals the whole changelog back through $GITHUB_OUTPUT with a heredoc
39+
# and fails on this repo's output ("Invalid value. Matching delimiter not
40+
# found 'EOF'"). Nothing here consumes that output — we only need
41+
# CHANGELOG.md on disk.
42+
- name: Install git-cliff
43+
env:
44+
GIT_CLIFF_VERSION: "2.13.1"
45+
run: |
46+
set -euo pipefail
47+
TARBALL="git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-gnu.tar.gz"
48+
curl -sSfL --retry 3 \
49+
"https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/${TARBALL}" \
50+
-o "$TARBALL"
51+
curl -sSfL --retry 3 \
52+
"https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/${TARBALL}.sha512" \
53+
-o "${TARBALL}.sha512"
54+
sha512sum -c "${TARBALL}.sha512"
55+
tar -xzf "$TARBALL"
56+
sudo install -m755 "git-cliff-${GIT_CLIFF_VERSION}/git-cliff" /usr/local/bin/git-cliff
57+
git-cliff --version
58+
59+
- name: Generate CHANGELOG.md
60+
run: git-cliff --config cliff.toml --output CHANGELOG.md
61+
62+
- name: Commit and push CHANGELOG.md
63+
uses: stefanzweifel/git-auto-commit-action@b863ae1933cb653a53c021fe36dbb774e1fb9403 # v5
64+
>>>>>>> emwulrd/main
3165
with:
3266
file_pattern: CHANGELOG.md
3367
commit_message: "chore(changelog): update changelog [skip ci]"

.github/workflows/contract-tests.yml

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,49 @@ on:
44
pull_request:
55
branches:
66
- main
7+
paths:
8+
- "Dechat/stellar-contracts/**"
9+
- ".github/workflows/contract-tests.yml"
710

811
jobs:
912
test:
1013
name: Run cargo test
1114
runs-on: ubuntu-latest
1215

16+
defaults:
17+
run:
18+
working-directory: Dechat/stellar-contracts
19+
1320
steps:
1421
- name: Checkout repository
22+
<<<<<<< HEAD
1523
uses: actions/checkout@v4
1624

1725
- name: Install Rust stable toolchain
1826
uses: dtolnay/rust-toolchain@stable
1927
with:
28+
=======
29+
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
30+
31+
- name: Install Rust stable toolchain
32+
uses: dtolnay/rust-toolchain@2c7215f132e9ebf062739d9130488b56d53c060c # stable
33+
with:
34+
toolchain: stable
35+
>>>>>>> emwulrd/main
2036
components: clippy
2137
targets: wasm32-unknown-unknown
2238

2339
- name: Cache Cargo dependencies
40+
<<<<<<< HEAD
2441
uses: Swatinem/rust-cache@v2
42+
=======
43+
uses: Swatinem/rust-cache@42dc69e1aa15d09112580998cf2ef0119e2e91ae # v2
44+
>>>>>>> emwulrd/main
2545
with:
26-
workspaces: stellar-contracts -> target
46+
workspaces: Dechat/stellar-contracts -> target
2747

2848
- name: Run clippy (deny warnings)
29-
run: cd stellar-contracts && cargo clippy --all-targets --all-features -- -D warnings
49+
run: cargo clippy --all-targets --all-features -- -D warnings
3050

3151
- name: Run contract tests
32-
run: cd stellar-contracts && cargo test
52+
run: cargo test

0 commit comments

Comments
 (0)