Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ HATS_CONTRACT_ADDRESS=
ANGRY_DWARF_HAT_ID=

# External APIs
# Optional; public CoinGecko price endpoint is used when unset.
COINGECKO_API_KEY=
11 changes: 9 additions & 2 deletions PROJECT_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ Homepage content:

The homepage should not include a recent activity feed in V1.

Balance refresh behavior:

- The homepage serves the latest cached treasury balance immediately.
- Any authenticated member may trigger a background refresh when cached balance data is missing or older than one hour.
- Stale data should remain readable and dated, with clear sync timing and subtle refreshing/updated UI states.

## 8. Data Sources

### Main Safe
Expand All @@ -166,9 +172,10 @@ The first automated onchain source is the main RaidGuild Safe on Gnosis.

The main Safe address is environment-configured.

The app should fetch:
The app should fetch current balances for USDC, xDAI, wxDAI, and wETH through the configured Gnosis RPC. Stable assets are valued 1:1 with USD. wETH uses CoinGecko pricing when available, with the API key optional.

Later main Safe ingestion should fetch:

- Current balances.
- Native transfers.
- ERC-20 transfers.
- Safe transaction metadata where useful.
Expand Down
40 changes: 40 additions & 0 deletions drizzle/0002_lovely_colossus.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
CREATE TYPE "public"."treasury_snapshot_status" AS ENUM('pending_live_sync', 'synced', 'stale_syncing', 'partial', 'failed');--> statement-breakpoint
CREATE TABLE "treasury_balance_assets" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"snapshot_id" uuid NOT NULL,
"symbol" text NOT NULL,
"name" text NOT NULL,
"decimals" integer NOT NULL,
"raw_amount" numeric(78, 0) NOT NULL,
"balance" numeric(36, 18) NOT NULL,
"usd_price" numeric(18, 8) NOT NULL,
"usd_value" numeric(18, 2) NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "treasury_balance_snapshots" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"account_address" text NOT NULL,
"chain_id" integer NOT NULL,
"status" "treasury_snapshot_status" NOT NULL,
"total_usd" numeric(18, 2) NOT NULL,
"synced_at" timestamp with time zone NOT NULL,
"error_message" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "treasury_balance_assets" ADD CONSTRAINT "treasury_balance_assets_snapshot_id_treasury_balance_snapshots_id_fk" FOREIGN KEY ("snapshot_id") REFERENCES "public"."treasury_balance_snapshots"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "treasury_balance_assets_snapshot_id_idx" ON "treasury_balance_assets" USING btree ("snapshot_id");--> statement-breakpoint
CREATE UNIQUE INDEX "treasury_balance_assets_snapshot_symbol_unique" ON "treasury_balance_assets" USING btree ("snapshot_id","symbol");--> statement-breakpoint
CREATE INDEX "treasury_balance_snapshots_account_idx" ON "treasury_balance_snapshots" USING btree ("chain_id","account_address");--> statement-breakpoint
CREATE INDEX "treasury_balance_snapshots_synced_at_idx" ON "treasury_balance_snapshots" USING btree ("synced_at");--> statement-breakpoint
CREATE TRIGGER "treasury_balance_assets_set_updated_at"
BEFORE UPDATE ON "treasury_balance_assets"
FOR EACH ROW
EXECUTE FUNCTION "public"."set_updated_at"();--> statement-breakpoint
CREATE TRIGGER "treasury_balance_snapshots_set_updated_at"
BEFORE UPDATE ON "treasury_balance_snapshots"
FOR EACH ROW
EXECUTE FUNCTION "public"."set_updated_at"();
Loading
Loading