Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f474402
✨ common: export app stack identifier
cruzdanilo Jul 9, 2026
eec9686
📈 server: use stack for sentry instrumentation
cruzdanilo Jul 9, 2026
87fcdb2
🧱 server: use node entrypoint as docker argument
cruzdanilo Jul 9, 2026
2c8db3b
➕ server: add google cloud secret manager
cruzdanilo Jul 9, 2026
1ebd138
✨ server: implement google secret manager
cruzdanilo Jul 9, 2026
e61f556
✨ server: introduce shared worker primitives
cruzdanilo Jul 24, 2026
c9f2986
✨ server: migrate webhook subscription to queue
aguxez Feb 16, 2026
d3cefe0
🎉 infra: create pulumi project
cruzdanilo Jul 7, 2026
8418e70
🔨 server: build worker entrypoints
cruzdanilo Jul 9, 2026
132d6be
🧱 infra: setup subscribe queue worker
cruzdanilo Jul 9, 2026
4619a6e
👷 github: restrict build credential exposure
cruzdanilo Jul 11, 2026
1ef8e8f
🧱 infra: setup ghcr artifact registry
cruzdanilo Jul 9, 2026
00b902f
🚚 server: rename keeper module to wallet
cruzdanilo Jul 9, 2026
539328f
✨ server: create wallet account by name
cruzdanilo Jul 9, 2026
6b43b40
➕ server: add google cloud kms dependencies
cruzdanilo Jul 9, 2026
b29bb03
✨ server: create wallet client by account name
cruzdanilo Jul 9, 2026
73dba9a
✨ server: automate panda refund withdrawal
cruzdanilo Jul 9, 2026
46606fc
🧱 infra: setup refund queue worker
cruzdanilo Jul 9, 2026
8a4ac13
🔧 infra: run typescript as native node esm
cruzdanilo Jul 17, 2026
c55591f
✨ server: process auto-credit in worker
cruzdanilo Jul 21, 2026
3a8ad8a
🧱 infra: setup credit queue worker
cruzdanilo Jul 22, 2026
316dc59
✨ server: process poke in worker
cruzdanilo Jul 22, 2026
01b11da
🧱 infra: setup poke queue worker
cruzdanilo Jul 22, 2026
6a3ef4f
✨ server: automate firewall allow after kyc approval
cruzdanilo Jul 22, 2026
99ba0fa
🧱 infra: setup allow queue worker
cruzdanilo Jul 22, 2026
6cc4040
⚗️ github: build base-sepolia from infra branch
cruzdanilo Jul 14, 2026
3aec496
🚧 github: meta infra
cruzdanilo Jul 17, 2026
9f635f8
🚧 server: workers
cruzdanilo Jul 24, 2026
16412f4
🚧
cruzdanilo Jul 17, 2026
7cc2320
🚧 server: hooks
cruzdanilo Jul 28, 2026
57620df
🗃️ server: add whatsapp id column to credentials
mainqueg Jul 16, 2026
31c6b9e
✨ server: add chat association endpoint
mainqueg Jul 23, 2026
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
5 changes: 5 additions & 0 deletions .changeset/afraid-mangos-follow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/infra": minor
---

🧱 setup credit queue worker
5 changes: 5 additions & 0 deletions .changeset/blue-bottles-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ automate firewall allow after kyc approval
5 changes: 5 additions & 0 deletions .changeset/bumpy-regions-read.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/infra": minor
---

🧱 setup poke queue worker
5 changes: 5 additions & 0 deletions .changeset/bumpy-toes-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ implement google secret manager
5 changes: 5 additions & 0 deletions .changeset/chubby-papayas-visit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/infra": minor
---

🧱 setup refund queue worker
5 changes: 5 additions & 0 deletions .changeset/free-lamps-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/infra": minor
---

🧱 setup allow queue worker
5 changes: 5 additions & 0 deletions .changeset/khaki-pugs-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/infra": minor
---

🧱 setup ghcr artifact registry
5 changes: 5 additions & 0 deletions .changeset/large-candies-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/infra": minor
---

🧱 setup subscribe queue worker
5 changes: 5 additions & 0 deletions .changeset/plain-pumas-relax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ migrate webhook subscription to queue
5 changes: 5 additions & 0 deletions .changeset/proud-tools-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ process poke in worker
5 changes: 5 additions & 0 deletions .changeset/short-radios-stand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ automate panda refund withdrawal
5 changes: 5 additions & 0 deletions .changeset/spicy-ideas-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/common": patch
---

✨ export app stack identifier
5 changes: 5 additions & 0 deletions .changeset/ten-planets-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

📈 use stack for sentry instrumentation
5 changes: 5 additions & 0 deletions .changeset/tender-foxes-feel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ process auto-credit in worker
2 changes: 1 addition & 1 deletion .changeset/version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ set -eo pipefail

pnpm changeset version
pnpm install --lockfile-only
git commit --all --amend --no-edit
git -c user.name=exa-version -c user.email=exa-version commit --all --amend --no-edit
5 changes: 5 additions & 0 deletions .changeset/warm-otters-associate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/server": patch
---

✨ add chat association endpoint
10 changes: 5 additions & 5 deletions .github/workflows/server-base-sepolia.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
name: server/base-sepolia
on:
push: { branches: [sandbox] }
push: { branches: [infra] }
jobs:
build:
uses: ./.github/workflows/server-build.yaml
secrets: inherit
with: { environment: base-sepolia }
with: { stack: base-sepolia, chain: 84532, devtools: true }
deploy:
needs: build
uses: ./.github/workflows/server-deploy.yaml
secrets: inherit
with: { environment: base-sepolia }
secrets:
DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
with: { stack: base-sepolia }
5 changes: 2 additions & 3 deletions .github/workflows/server-base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ on:
jobs:
build:
uses: ./.github/workflows/server-build.yaml
secrets: inherit
with: { environment: base }
with: { stack: base, chain: 8453 }
deploy:
needs: build
uses: ./.github/workflows/server-deploy.yaml
secrets: inherit
with: { environment: base }
with: { stack: base }
53 changes: 9 additions & 44 deletions .github/workflows/server-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ name: server/build
on:
workflow_call:
inputs:
environment: { required: true, type: string }
secrets:
SENTRY_AUTH_TOKEN:
stack: { required: true, type: string }
chain: { required: true, type: number }
domain: { type: string }
devtools: { default: false, type: boolean }
jobs:
docker:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
permissions: { contents: read, packages: write, attestations: write, id-token: write }
env:
IMAGE: ghcr.io/${{ github.repository }}-${{ inputs.environment }}
IMAGE: ghcr.io/${{ github.repository }}-${{ inputs.stack }}
steps:
- uses: actions/checkout@v6
with: { fetch-depth: 0, fetch-tags: true }
with: { fetch-depth: 0, fetch-tags: true, persist-credentials: false }
- uses: docker/setup-buildx-action@v4 # cspell:ignore buildx
- uses: docker/metadata-action@v6
id: meta
Expand All @@ -40,46 +40,11 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
CHAIN_ID=${{ vars.CHAIN_ID }}
APP_DOMAIN=${{ vars.APP_DOMAIN }}
EXPO_PUBLIC_DEVTOOLS=${{ vars.EXPO_PUBLIC_DEVTOOLS }}
CHAIN_ID=${{ inputs.chain }}
APP_DOMAIN=${{ inputs.domain || format('{0}.exactly.app', inputs.stack) }}
EXPO_PUBLIC_DEVTOOLS=${{ inputs.devtools }}
- uses: actions/attest-build-provenance@v4
with:
subject-name: ${{ env.IMAGE }}
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true
- run: |
docker pull ${{ env.IMAGE }}@${{ steps.build.outputs.digest }}
docker create --name extract ${{ env.IMAGE }}@${{ steps.build.outputs.digest }}
docker cp extract:/prod/server/dist ./server/dist
mkdir -p ./server/generated
docker cp extract:/prod/server/generated/release.js ./server/generated/release.js
docker rm extract
echo "release=$(node -e 'console.log(require(`./server/generated/release`))')" >> $GITHUB_OUTPUT
id: extract
- id: commits
if: inputs.environment == 'production'
run: |
currentTag="$GITHUB_REF_NAME"
previousTag=$(git for-each-ref 'refs/tags/@exactly/server@*' --sort=-version:refname --format='%(refname:short)' | while read -r tag; do [ "$tag" = "$currentTag" ] && continue; git merge-base --is-ancestor "$tag" "$GITHUB_SHA" && { echo "$tag"; break; }; done)
if [ -n "$previousTag" ]; then
echo "mode=manual" >> "$GITHUB_OUTPUT"
echo "repo=$GITHUB_REPOSITORY" >> "$GITHUB_OUTPUT"
echo "commit=$GITHUB_SHA" >> "$GITHUB_OUTPUT"
echo "previous_commit=$(git rev-list -n 1 "$previousTag")" >> "$GITHUB_OUTPUT"
echo "previous_tag=$previousTag" >> "$GITHUB_OUTPUT"
else
echo "mode=auto" >> "$GITHUB_OUTPUT"
fi
- uses: getsentry/action-release@v3 # cspell:ignore getsentry
if: inputs.environment == 'production'
env: { SENTRY_ORG: exactly, SENTRY_PROJECT: server, SENTRY_AUTH_TOKEN: "${{ secrets.SENTRY_AUTH_TOKEN }}" }
with:
commit: ${{ steps.commits.outputs.commit }}
environment: ${{ inputs.environment }}
previous_commit: ${{ steps.commits.outputs.previous_commit }}
repo: ${{ steps.commits.outputs.repo }}
release: ${{ steps.extract.outputs.release }}
set_commits: ${{ steps.commits.outputs.mode }}
sourcemaps: server/dist
inject: false
88 changes: 79 additions & 9 deletions .github/workflows/server-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,96 @@ name: server/deploy
on:
workflow_call:
inputs:
environment:
required: true
type: string
stack: { required: true, type: string }
domain: { type: string }
secrets:
DIGITALOCEAN_TOKEN:
SENTRY_AUTH_TOKEN:
concurrency:
group: server-deploy-${{ inputs.stack }}
cancel-in-progress: false
jobs:
infra:
runs-on: ubuntu-latest
environment: ${{ inputs.stack }}
permissions: { contents: read, id-token: write }
env:
PULUMI_CONFIG_PASSPHRASE: ""
STACK: ${{ inputs.stack }}
steps:
- uses: actions/checkout@v6
with: { persist-credentials: false }
- id: account
run: echo "email=github-$STACK@$(yq -er '.config."gcp:project"' "infra/Pulumi.$STACK.yaml").iam.gserviceaccount.com" >> "$GITHUB_OUTPUT"
- uses: google-github-actions/auth@v3
with:
workload_identity_provider: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ steps.account.outputs.email }}
- uses: actions/setup-node@v6
with: { node-version: 24, check-latest: true, package-manager-cache: false }
- uses: foundry-rs/foundry-toolchain@v1
with: { version: v1.5.1 }
- run: corepack enable
- run: pnpm install --frozen-lockfile
- uses: pulumi/actions@v7
- run: pulumi login "gs://exa-pulumi-state/$STACK"
- run: pulumi stack select "$STACK" --create --cwd infra
- run: pulumi up --stack "$STACK" --cwd infra --refresh --yes --config "exa:serverImage=sha-$GITHUB_SHA"
digitalocean:
runs-on: ubuntu-latest
environment: { name: "${{ inputs.environment }}", url: "https://${{ vars.APP_DOMAIN }}" }
concurrency:
group: server-deploy-${{ inputs.environment }}
cancel-in-progress: true
environment: { name: "${{ inputs.stack }}", url: "https://${{ vars.APP_DOMAIN }}" }
permissions: { contents: read, packages: read }
env:
APP_DOMAIN: ${{ inputs.domain || format('{0}.exactly.app', inputs.stack) }}
CHAIN_ID: ${{ vars.CHAIN_ID }}
APP_DOMAIN: ${{ vars.APP_DOMAIN }}
IMAGE: ghcr.io/${{ github.repository }}-${{ inputs.stack }}
steps:
- uses: digitalocean/app_action/deploy@v2
env: { IMAGE_TAG_SERVER: "sha-${{ github.sha }}" }
with:
app_name: ${{ inputs.environment }}
app_name: ${{ inputs.stack }}
token: ${{ secrets.DIGITALOCEAN_TOKEN }}
print_build_logs: true
print_deploy_logs: true
- uses: actions/checkout@v6
if: inputs.stack == 'production'
with: { fetch-depth: 0, fetch-tags: true, persist-credentials: false }
- uses: docker/login-action@v4
if: inputs.stack == 'production'
with: { registry: ghcr.io, username: "${{ github.repository_owner }}", password: "${{ secrets.GITHUB_TOKEN }}" }
- run: |
docker pull "$IMAGE:sha-$GITHUB_SHA"
docker create --name extract "$IMAGE:sha-$GITHUB_SHA"
docker cp extract:/prod/server/dist ./server/dist
mkdir -p ./server/generated
docker cp extract:/prod/server/generated/release.js ./server/generated/release.js
docker rm extract
echo "release=$(node -e 'console.log(require(`./server/generated/release`))')" >> $GITHUB_OUTPUT
id: extract
if: inputs.stack == 'production'
- id: commits
if: inputs.stack == 'production'
run: |
currentTag="$GITHUB_REF_NAME"
previousTag=$(git for-each-ref 'refs/tags/@exactly/server@*' --sort=-version:refname --format='%(refname:short)' | while read -r tag; do [ "$tag" = "$currentTag" ] && continue; git merge-base --is-ancestor "$tag" "$GITHUB_SHA" && { echo "$tag"; break; }; done)
if [ -n "$previousTag" ]; then
echo "mode=manual" >> "$GITHUB_OUTPUT"
echo "repo=$GITHUB_REPOSITORY" >> "$GITHUB_OUTPUT"
echo "commit=$GITHUB_SHA" >> "$GITHUB_OUTPUT"
echo "previous_commit=$(git rev-list -n 1 "$previousTag")" >> "$GITHUB_OUTPUT"
echo "previous_tag=$previousTag" >> "$GITHUB_OUTPUT"
else
echo "mode=auto" >> "$GITHUB_OUTPUT"
fi
- uses: getsentry/action-release@v3 # cspell:ignore getsentry
if: inputs.stack == 'production'
env: { SENTRY_ORG: exactly, SENTRY_PROJECT: server, SENTRY_AUTH_TOKEN: "${{ secrets.SENTRY_AUTH_TOKEN }}" }
with:
commit: ${{ steps.commits.outputs.commit }}
environment: ${{ inputs.stack }}
previous_commit: ${{ steps.commits.outputs.previous_commit }}
repo: ${{ steps.commits.outputs.repo }}
release: ${{ steps.extract.outputs.release }}
set_commits: ${{ steps.commits.outputs.mode }}
sourcemaps: server/dist
inject: false
5 changes: 2 additions & 3 deletions .github/workflows/server-production.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ on:
jobs:
build:
uses: ./.github/workflows/server-build.yaml
secrets: inherit
with: { environment: production }
with: { stack: production, chain: 10, domain: web.exactly.app }
deploy:
needs: build
uses: ./.github/workflows/server-deploy.yaml
secrets: inherit
with: { environment: production }
with: { stack: production, domain: web.exactly.app }
5 changes: 2 additions & 3 deletions .github/workflows/server-sandbox.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ on:
jobs:
build:
uses: ./.github/workflows/server-build.yaml
secrets: inherit
with: { environment: sandbox }
with: { stack: sandbox, chain: 11155420, devtools: true }
deploy:
needs: build
uses: ./.github/workflows/server-deploy.yaml
secrets: inherit
with: { environment: sandbox }
with: { stack: sandbox }
2 changes: 1 addition & 1 deletion .github/workflows/substreams-build.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: substreams/build
on: { push: { tags: ["@exactly/substreams@*"] }, workflow_dispatch: {} }
on: { push: { tags: ["@exactly/substreams@*"] } }
jobs:
docker:
runs-on: ubuntu-latest
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
name: test
on:
push:
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
Expand Down
20 changes: 11 additions & 9 deletions .github/workflows/version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ jobs:
version:
environment: version
runs-on: ubuntu-latest
permissions: { contents: read }
steps:
- uses: actions/checkout@v6
with: { token: "${{ secrets.RELEASE_GITHUB_TOKEN }}" }
- uses: actions/setup-node@v6
with: { node-version: 24, check-latest: true, package-manager-cache: false }
- uses: foundry-rs/foundry-toolchain@v1
Expand All @@ -26,17 +26,19 @@ jobs:
.reverse()
.join(", "))' >> $GITHUB_OUTPUT
rm status.json
- uses: crazy-max/ghaction-import-gpg@v7 # cspell:ignore ghaction
- uses: actions/create-github-app-token@v3
id: github
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
git_user_signingkey: true # cspell:ignore signingkey
git_commit_gpgsign: true # cspell:ignore gpgsign
- uses: changesets/action@v1
client-id: Iv23liuyLJGozoujn17O # cspell:ignore Iv23liuyLJGozoujn17O
private-key: ${{ secrets.EXA_VERSION_KEY }}
permission-contents: write
permission-pull-requests: write
- id: changesets
uses: changesets/action@v1
with:
title: ${{ steps.title.outputs.title }}
github-token: ${{ steps.github.outputs.token }}
commitMode: github-api
publish: pnpm changeset publish
version: ./.changeset/version.sh
prDraft: create
setupGitUser: false
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ extracting a value into a variable and extracting logic into a function are the
- `contracts`: the solidity smart contracts (`@exactly/plugin`).
- `common`: shared utilities (`@exactly/common`).
- `docs`: astro-based documentation (`@exactly/docs`).
- `infra`: pulumi gcp infrastructure (`@exactly/infra`).
- `substreams`: rust blockchain indexer (`@exactly/substreams`).
- `.maestro`: end-to-end test scripts (`@exactly/e2e`).
- **running tasks**: always use `pnpm nx` — never bare `nx`, `npx`, or `pnpm --filter`.
Expand Down
Loading
Loading