commit 4ef5340afc69bad33cce19164333eff29b80df8c
parent 40ebaac9095e506c9453b2936ed2771353d2c90d
Author: triesap <tyson@radroots.org>
Date: Thu, 11 Jun 2026 06:22:05 -0700
feat(events-bindings): generate events package
Diffstat:
10 files changed, 429 insertions(+), 9 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -681,6 +681,7 @@ name = "radroots_sdk_xtask"
version = "0.1.0"
dependencies = [
"radroots_core_bindings",
+ "radroots_events_bindings",
"radroots_events_indexed_bindings",
"radroots_identity_bindings",
"radroots_types_bindings",
diff --git a/crates/events_bindings/src/lib.rs b/crates/events_bindings/src/lib.rs
@@ -1 +1,27 @@
pub use radroots_events as upstream;
+
+pub const TYPES_TS: &str =
+ include_str!("../../../testdata/baseline/current-radroots-generated/events/types.ts");
+pub const CONSTANTS_TS: &str =
+ include_str!("../../../testdata/baseline/current-radroots-generated/events/constants.ts");
+pub const KINDS_TS: &str =
+ include_str!("../../../testdata/baseline/current-radroots-generated/events/kinds.ts");
+
+#[cfg(test)]
+mod tests {
+ use super::{CONSTANTS_TS, KINDS_TS, TYPES_TS};
+
+ #[test]
+ fn preserves_event_type_exports() {
+ assert!(TYPES_TS.contains("export type RadrootsListing"));
+ assert!(TYPES_TS.contains("export type RadrootsJobInput"));
+ assert!(TYPES_TS.contains("export type RadrootsTradeOrderRequested"));
+ }
+
+ #[test]
+ fn preserves_event_constant_exports() {
+ assert!(CONSTANTS_TS.contains("RADROOTS_LISTING_PRODUCT_TAG_KEYS"));
+ assert!(KINDS_TS.contains("KIND_LISTING"));
+ assert!(KINDS_TS.contains("KIND_TRADE_LISTING_ORDER_REQ"));
+ }
+}
diff --git a/crates/xtask/Cargo.toml b/crates/xtask/Cargo.toml
@@ -14,6 +14,7 @@ path = "src/main.rs"
[dependencies]
radroots_core_bindings = { path = "../core_bindings" }
+radroots_events_bindings = { path = "../events_bindings" }
radroots_events_indexed_bindings = { path = "../events_indexed_bindings" }
radroots_identity_bindings = { path = "../identity_bindings" }
radroots_types_bindings = { path = "../types_bindings" }
diff --git a/crates/xtask/src/output.rs b/crates/xtask/src/output.rs
@@ -3,7 +3,7 @@ use crate::{
manifest::package_manifest,
package_matrix::{PackageSpec, package_specs},
ts::{
- generated_constants_file, generated_header, generated_types_file,
+ generated_constants_file, generated_header, generated_kinds_file, generated_types_file,
strip_legacy_generated_header,
},
};
@@ -11,7 +11,9 @@ use crate::{
pub struct PackageOutput {
pub spec: PackageSpec,
pub types_ts: Option<&'static str>,
+ pub types_imports_ts: Option<&'static str>,
pub constants_ts: Option<&'static str>,
+ pub kinds_ts: Option<&'static str>,
}
pub struct GeneratedFile {
@@ -25,13 +27,19 @@ impl PackageOutput {
if let Some(types_ts) = self.types_ts {
files.push(GeneratedFile {
relative_path: format!("src/generated/{}", generated_types_file()),
- contents: render_ts(types_ts),
+ contents: render_ts(types_ts, self.types_imports_ts),
});
}
if let Some(constants_ts) = self.constants_ts {
files.push(GeneratedFile {
relative_path: format!("src/generated/{}", generated_constants_file()),
- contents: render_ts(constants_ts),
+ contents: render_ts(constants_ts, None),
+ });
+ }
+ if let Some(kinds_ts) = self.kinds_ts {
+ files.push(GeneratedFile {
+ relative_path: format!("src/generated/{}", generated_kinds_file()),
+ contents: render_ts(kinds_ts, None),
});
}
files.push(GeneratedFile {
@@ -51,22 +59,37 @@ pub fn package_outputs() -> Vec<PackageOutput> {
PackageOutput {
spec: spec_by_key("core"),
types_ts: Some(radroots_core_bindings::TYPES_TS),
+ types_imports_ts: None,
constants_ts: None,
+ kinds_ts: None,
+ },
+ PackageOutput {
+ spec: spec_by_key("events"),
+ types_ts: Some(radroots_events_bindings::TYPES_TS),
+ types_imports_ts: Some(EVENTS_TYPES_IMPORTS_TS),
+ constants_ts: Some(radroots_events_bindings::CONSTANTS_TS),
+ kinds_ts: Some(radroots_events_bindings::KINDS_TS),
},
PackageOutput {
spec: spec_by_key("events_indexed"),
types_ts: Some(radroots_events_indexed_bindings::TYPES_TS),
+ types_imports_ts: None,
constants_ts: None,
+ kinds_ts: None,
},
PackageOutput {
spec: spec_by_key("identity"),
types_ts: None,
+ types_imports_ts: None,
constants_ts: Some(radroots_identity_bindings::CONSTANTS_TS),
+ kinds_ts: None,
},
PackageOutput {
spec: spec_by_key("types"),
types_ts: Some(radroots_types_bindings::TYPES_TS),
+ types_imports_ts: None,
constants_ts: None,
+ kinds_ts: None,
},
]
}
@@ -79,11 +102,25 @@ fn spec_by_key(key: &str) -> PackageSpec {
.unwrap_or_else(|| panic!("missing package spec for {key}"))
}
-fn render_ts(source: &str) -> String {
+fn render_ts(source: &str, imports: Option<&str>) -> String {
let body = strip_legacy_generated_header(source);
- format!("{}{}", generated_header(), body.trim_start())
+ let imports = imports.unwrap_or("");
+ format!("{}{}{}", generated_header(), imports, body.trim_start())
}
+const EVENTS_TYPES_IMPORTS_TS: &str = r#"import type {
+ RadrootsCoreCurrency,
+ RadrootsCoreDecimal,
+ RadrootsCoreDiscount,
+ RadrootsCoreDiscountValue,
+ RadrootsCoreMoney,
+ RadrootsCoreQuantity,
+ RadrootsCoreQuantityPrice,
+ RadrootsCoreUnit,
+} from "@radroots/core-bindings";
+
+"#;
+
fn render_manifest(spec: PackageSpec) -> String {
let mut value = package_manifest(spec);
value["generated"] = serde_json::Value::Bool(true);
@@ -101,6 +138,9 @@ fn render_index(output: &PackageOutput) -> String {
if output.constants_ts.is_some() {
lines.push("export * from \"./generated/constants.js\";");
}
+ if output.kinds_ts.is_some() {
+ lines.push("export * from \"./generated/kinds.js\";");
+ }
if lines.is_empty() {
lines.push("export {};");
}
@@ -113,18 +153,31 @@ mod tests {
#[test]
fn renders_sdk_header() {
- let output = render_ts("// legacy\n\nexport type A = string;\n");
+ let output = render_ts("// legacy\n\nexport type A = string;\n", None);
assert!(output.starts_with("// @generated by cargo xtask generate ts"));
assert!(output.contains("export type A = string;"));
}
#[test]
+ fn renders_import_prelude_after_header() {
+ let output = render_ts(
+ "export type A = B;\n",
+ Some("import type { B } from \"b\";\n\n"),
+ );
+ assert!(output.starts_with(
+ "// @generated by cargo xtask generate ts\n// Do not edit by hand.\nimport type"
+ ));
+ assert!(output.contains("export type A = B;"));
+ }
+
+ #[test]
fn includes_core_and_types_outputs() {
let package_names = package_outputs()
.into_iter()
.map(|output| output.spec.package_name)
.collect::<Vec<_>>();
assert!(package_names.contains(&"@radroots/core-bindings"));
+ assert!(package_names.contains(&"@radroots/events-bindings"));
assert!(package_names.contains(&"@radroots/events-indexed-bindings"));
assert!(package_names.contains(&"@radroots/identity-bindings"));
assert!(package_names.contains(&"@radroots/types-bindings"));
diff --git a/crates/xtask/src/ts.rs b/crates/xtask/src/ts.rs
@@ -10,6 +10,10 @@ pub fn generated_constants_file() -> &'static str {
"constants.ts"
}
+pub fn generated_kinds_file() -> &'static str {
+ "kinds.ts"
+}
+
pub fn normalize_lf(value: &str) -> String {
value.replace("\r\n", "\n")
}
@@ -25,8 +29,8 @@ pub fn strip_legacy_generated_header(value: &str) -> String {
#[cfg(test)]
mod tests {
use super::{
- generated_constants_file, generated_header, generated_types_file, normalize_lf,
- strip_legacy_generated_header,
+ generated_constants_file, generated_header, generated_kinds_file, generated_types_file,
+ normalize_lf, strip_legacy_generated_header,
};
#[test]
@@ -41,6 +45,7 @@ mod tests {
fn generated_file_names_are_stable() {
assert_eq!(generated_types_file(), "types.ts");
assert_eq!(generated_constants_file(), "constants.ts");
+ assert_eq!(generated_kinds_file(), "kinds.ts");
}
#[test]
diff --git a/packages/events-bindings/src/generated/constants.ts b/packages/events-bindings/src/generated/constants.ts
@@ -0,0 +1,5 @@
+// @generated by cargo xtask generate ts
+// Do not edit by hand.
+import type { RadrootsListingProductTagKeys } from "./types.js";
+
+export const RADROOTS_LISTING_PRODUCT_TAG_KEYS: RadrootsListingProductTagKeys = ["key", "title", "category", "summary", "process", "lot", "location", "profile", "year"];
diff --git a/packages/events-bindings/src/generated/kinds.ts b/packages/events-bindings/src/generated/kinds.ts
@@ -0,0 +1,89 @@
+// @generated by cargo xtask generate ts
+// Do not edit by hand.
+export const KIND_PROFILE = 0;
+export const KIND_POST = 1;
+export const KIND_FOLLOW = 3;
+export const KIND_REACTION = 7;
+export const KIND_SEAL = 13;
+export const KIND_MESSAGE = 14;
+export const KIND_MESSAGE_FILE = 15;
+export const KIND_GIFT_WRAP = 1059;
+export const KIND_COMMENT = 1111;
+export const KIND_GEOCHAT = 20000;
+export const KIND_LIST_MUTE = 10000;
+export const KIND_LIST_PINNED_NOTES = 10001;
+export const KIND_LIST_READ_WRITE_RELAYS = 10002;
+export const KIND_LIST_BOOKMARKS = 10003;
+export const KIND_LIST_COMMUNITIES = 10004;
+export const KIND_LIST_PUBLIC_CHATS = 10005;
+export const KIND_LIST_BLOCKED_RELAYS = 10006;
+export const KIND_LIST_SEARCH_RELAYS = 10007;
+export const KIND_LIST_SIMPLE_GROUPS = 10009;
+export const KIND_LIST_RELAY_FEEDS = 10012;
+export const KIND_LIST_INTERESTS = 10015;
+export const KIND_LIST_MEDIA_FOLLOWS = 10020;
+export const KIND_LIST_EMOJIS = 10030;
+export const KIND_LIST_DM_RELAYS = 10050;
+export const KIND_LIST_GOOD_WIKI_AUTHORS = 10101;
+export const KIND_LIST_GOOD_WIKI_RELAYS = 10102;
+export const KIND_LIST_SET_FOLLOW = 30000;
+export const KIND_LIST_SET_GENERIC = 30001;
+export const KIND_LIST_SET_RELAY = 30002;
+export const KIND_LIST_SET_BOOKMARK = 30003;
+export const KIND_LIST_SET_CURATION = 30004;
+export const KIND_LIST_SET_VIDEO = 30005;
+export const KIND_LIST_SET_PICTURE = 30006;
+export const KIND_LIST_SET_KIND_MUTE = 30007;
+export const KIND_LIST_SET_INTEREST = 30015;
+export const KIND_LIST_SET_EMOJI = 30030;
+export const KIND_LIST_SET_RELEASE_ARTIFACT = 30063;
+export const KIND_LIST_SET_APP_CURATION = 30267;
+export const KIND_LIST_SET_CALENDAR = 31924;
+export const KIND_LIST_SET_STARTER_PACK = 39089;
+export const KIND_LIST_SET_MEDIA_STARTER_PACK = 39092;
+export const KIND_FARM = 30340;
+export const KIND_PLOT = 30350;
+export const KIND_COOP = 30360;
+export const KIND_DOCUMENT = 30361;
+export const KIND_RESOURCE_AREA = 30370;
+export const KIND_RESOURCE_HARVEST_CAP = 30371;
+export const KIND_ACCOUNT_CLAIM = 30380;
+export const KIND_APP_DATA = 30078;
+export const KIND_LISTING = 30402;
+export const KIND_APPLICATION_HANDLER = 31990;
+export const KIND_TRADE_LISTING_VALIDATE_REQ = 5321;
+export const KIND_TRADE_LISTING_VALIDATE_RES = 6321;
+export const KIND_WORKER_TRADE_TRANSITION_PROOF_REQ = 5322;
+export const KIND_WORKER_TRADE_TRANSITION_PROOF_RES = 6322;
+export const KIND_TRADE_ORDER_REQUEST = 3422;
+export const KIND_TRADE_ORDER_RESPONSE = 3423;
+export const KIND_TRADE_ORDER_DECISION = 3423;
+export const KIND_TRADE_ORDER_REVISION = 3424;
+export const KIND_TRADE_ORDER_REVISION_RESPONSE = 3425;
+export const KIND_TRADE_QUESTION = 3426;
+export const KIND_TRADE_ANSWER = 3427;
+export const KIND_TRADE_DISCOUNT_REQUEST = 3428;
+export const KIND_TRADE_DISCOUNT_OFFER = 3429;
+export const KIND_TRADE_DISCOUNT_ACCEPT = 3430;
+export const KIND_TRADE_FORBIDDEN_3431 = 3431;
+export const KIND_TRADE_CANCEL = 3432;
+export const KIND_TRADE_FULFILLMENT_UPDATE = 3433;
+export const KIND_TRADE_RECEIPT = 3434;
+export const KIND_TRADE_VALIDATION_RECEIPT = 3440;
+export const KIND_TRADE_LISTING_ORDER_REQ = 3422;
+export const KIND_TRADE_LISTING_ORDER_RES = 3423;
+export const KIND_TRADE_LISTING_ORDER_REVISION_REQ = 3424;
+export const KIND_TRADE_LISTING_ORDER_REVISION_RES = 3425;
+export const KIND_TRADE_LISTING_QUESTION_REQ = 3426;
+export const KIND_TRADE_LISTING_ANSWER_RES = 3427;
+export const KIND_TRADE_LISTING_DISCOUNT_REQ = 3428;
+export const KIND_TRADE_LISTING_DISCOUNT_OFFER_RES = 3429;
+export const KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ = 3430;
+export const KIND_TRADE_LISTING_CANCEL_REQ = 3432;
+export const KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ = 3433;
+export const KIND_TRADE_LISTING_RECEIPT_REQ = 3434;
+export const KIND_JOB_REQUEST_MIN = 5000;
+export const KIND_JOB_REQUEST_MAX = 5999;
+export const KIND_JOB_RESULT_MIN = 6000;
+export const KIND_JOB_RESULT_MAX = 6999;
+export const KIND_JOB_FEEDBACK = 7000;
diff --git a/packages/events-bindings/src/generated/sdk-manifest.json b/packages/events-bindings/src/generated/sdk-manifest.json
@@ -0,0 +1,6 @@
+{
+ "crate": "radroots_events_bindings",
+ "generated": true,
+ "generator": "radroots_sdk_xtask",
+ "package": "@radroots/events-bindings"
+}
diff --git a/packages/events-bindings/src/generated/types.ts b/packages/events-bindings/src/generated/types.ts
@@ -0,0 +1,232 @@
+// @generated by cargo xtask generate ts
+// Do not edit by hand.
+import type {
+ RadrootsCoreCurrency,
+ RadrootsCoreDecimal,
+ RadrootsCoreDiscount,
+ RadrootsCoreDiscountValue,
+ RadrootsCoreMoney,
+ RadrootsCoreQuantity,
+ RadrootsCoreQuantityPrice,
+ RadrootsCoreUnit,
+} from "@radroots/core-bindings";
+
+export type JobFeedbackStatus = "payment_required" | "processing" | "error" | "success" | "partial";
+
+export type JobInputType = "url" | "event" | "job" | "text";
+
+export type JobPaymentRequest = { amount_sat: number, bolt11?: string | null, };
+
+export type RadrootsAccountClaim = { username: string, pubkey: string, nip05?: string | null, };
+
+export type RadrootsActiveTradeEnvelope<T> = { version: number, domain: RadrootsTradeDomain, type: RadrootsActiveTradeMessageType, order_id: string, listing_addr: string, payload: T, };
+
+export type RadrootsActiveTradeFulfillmentState = "accepted_not_fulfilled" | "preparing" | "ready_for_pickup" | "out_for_delivery" | "delivered" | "seller_cancelled";
+
+export type RadrootsActiveTradeMessageType = "TradeOrderRequested" | "TradeOrderDecision" | "TradeOrderRevisionProposed" | "TradeOrderRevisionDecision" | "TradeOrderCancelled" | "TradeFulfillmentUpdated" | "TradeBuyerReceipt" | "TradePaymentRecorded" | "TradeSettlementDecision";
+
+export type RadrootsAppData = { d_tag: string, content: string, };
+
+export type RadrootsComment = { root: RadrootsNostrEventRef, parent: RadrootsNostrEventRef, content: string, };
+
+export type RadrootsCoop = { d_tag: string, name: string, about?: string | null, website?: string | null, picture?: string | null, banner?: string | null, location?: RadrootsCoopLocation | null, tags?: string[] | null, };
+
+export type RadrootsCoopLocation = { primary?: string | null, city?: string | null, region?: string | null, country?: string | null, gcs: RadrootsGcsLocation, };
+
+export type RadrootsCoopRef = { pubkey: string, d_tag: string, };
+
+export type RadrootsDocument = { d_tag: string, doc_type: string, title: string, version: string, summary?: string | null, effective_at?: number | null, body_markdown?: string | null, subject: RadrootsDocumentSubject, tags?: string[] | null, };
+
+export type RadrootsDocumentSubject = { pubkey: string, address?: string | null, };
+
+export type RadrootsFarm = { d_tag: string, name: string, about?: string | null, website?: string | null, picture?: string | null, banner?: string | null, location?: RadrootsFarmLocation | null, tags?: string[] | null, };
+
+export type RadrootsFarmLocation = { primary?: string | null, city?: string | null, region?: string | null, country?: string | null, gcs?: RadrootsGcsLocation | null, };
+
+export type RadrootsFarmRef = { pubkey: string, d_tag: string, };
+
+export type RadrootsFollow = { list: Array<RadrootsFollowProfile>, };
+
+export type RadrootsFollowProfile = { published_at: number, public_key: string, relay_url?: string | null, contact_name?: string | null, };
+
+export type RadrootsGcsLocation = { lat: number, lng: number, geohash: string, point: RadrootsGeoJsonPoint, polygon: RadrootsGeoJsonPolygon, accuracy?: number | null, altitude?: number | null, tag_0?: string | null, label?: string | null, area?: number | null, elevation?: number | null, soil?: string | null, climate?: string | null, gc_id?: string | null, gc_name?: string | null, gc_admin1_id?: string | null, gc_admin1_name?: string | null, gc_country_id?: string | null, gc_country_name?: string | null, };
+
+export type RadrootsGeoChat = { geohash: string, content: string, nickname?: string | null, teleported: boolean, };
+
+export type RadrootsGeoJsonPoint = { type: string, coordinates: [number, number], };
+
+export type RadrootsGeoJsonPolygon = { type: string, coordinates: Array<Array<[number, number]>>, };
+
+export type RadrootsGiftWrap = { recipient: RadrootsGiftWrapRecipient, content: string, expiration?: number | null, };
+
+export type RadrootsGiftWrapRecipient = { public_key: string, relay_url?: string | null, };
+
+export type RadrootsJobFeedback = { kind: number, status: JobFeedbackStatus, extra_info?: string | null, request_event: RadrootsNostrEventPtr, customer_pubkey?: string | null, payment?: JobPaymentRequest | null, content?: string | null, encrypted: boolean, };
+
+export type RadrootsJobInput = { data: string, input_type: JobInputType, relay?: string | null, marker?: string | null, };
+
+export type RadrootsJobParam = { key: string, value: string, };
+
+export type RadrootsJobRequest = { kind: number, inputs: Array<RadrootsJobInput>, output?: string | null, params: Array<RadrootsJobParam>, bid_sat?: number | null, relays: Array<string>, providers: Array<string>, topics: Array<string>, encrypted: boolean, };
+
+export type RadrootsJobResult = { kind: number, request_event: RadrootsNostrEventPtr, request_json?: string | null, inputs: Array<RadrootsJobInput>, customer_pubkey?: string | null, payment?: JobPaymentRequest | null, content?: string | null, encrypted: boolean, };
+
+export type RadrootsList = { content: string, entries: Array<RadrootsListEntry>, };
+
+export type RadrootsListEntry = { tag: string, values: Array<string>, };
+
+export type RadrootsListSet = { d_tag: string, content: string, entries: Array<RadrootsListEntry>, title?: string | null, description?: string | null, image?: string | null, };
+
+export type RadrootsListing = { d_tag: string, farm: RadrootsFarmRef, product: RadrootsListingProduct, primary_bin_id: string, bins: Array<RadrootsListingBin>, resource_area?: RadrootsResourceAreaRef | null, plot?: RadrootsPlotRef | null, discounts?: RadrootsCoreDiscount[] | null, inventory_available?: RadrootsCoreDecimal | null, availability?: RadrootsListingAvailability | null, delivery_method?: RadrootsListingDeliveryMethod | null, location?: RadrootsListingLocation | null, images?: RadrootsListingImage[] | null, };
+
+export type RadrootsListingAvailability = { "kind": "window", "amount": { start?: number | null, end?: number | null, } } | { "kind": "status", "amount": { status: RadrootsListingStatus, } };
+
+export type RadrootsListingBin = { bin_id: string, quantity: RadrootsCoreQuantity, price_per_canonical_unit: RadrootsCoreQuantityPrice, display_amount?: RadrootsCoreDecimal | null, display_unit?: RadrootsCoreUnit | null, display_label?: string | null, display_price?: RadrootsCoreMoney | null, display_price_unit?: RadrootsCoreUnit | null, };
+
+export type RadrootsListingDeliveryMethod = { "kind": "pickup" } | { "kind": "local_delivery" } | { "kind": "shipping" } | { "kind": "other", "amount": { method: string, } };
+
+export type RadrootsListingImage = { url: string, size?: RadrootsListingImageSize | null, };
+
+export type RadrootsListingImageSize = { w: number, h: number, };
+
+export type RadrootsListingLocation = { primary: string, city?: string | null, region?: string | null, country?: string | null, lat?: number | null, lng?: number | null, geohash?: string | null, };
+
+export type RadrootsListingProduct = { key: string, title: string, category: string, summary?: string | null, process?: string | null, lot?: string | null, location?: string | null, profile?: string | null, year?: string | null, };
+
+export type RadrootsListingProductTagKeys = readonly ["key", "title", "category", "summary", "process", "lot", "location", "profile", "year"];
+
+export type RadrootsListingStatus = { "kind": "active" } | { "kind": "sold" } | { "kind": "other", "amount": { value: string, } };
+
+export type RadrootsMessage = { recipients: Array<RadrootsMessageRecipient>, content: string, reply_to?: RadrootsNostrEventPtr | null, subject?: string | null, };
+
+export type RadrootsMessageFile = { recipients: Array<RadrootsMessageRecipient>, file_url: string, reply_to?: RadrootsNostrEventPtr | null, subject?: string | null, file_type: string, encryption_algorithm: string, decryption_key: string, decryption_nonce: string, encrypted_hash: string, original_hash?: string | null, size?: number | null, dimensions?: RadrootsMessageFileDimensions | null, blurhash?: string | null, thumb?: string | null, fallbacks: Array<string>, };
+
+export type RadrootsMessageFileDimensions = { w: number, h: number, };
+
+export type RadrootsMessageRecipient = { public_key: string, relay_url?: string | null, };
+
+export type RadrootsNostrEvent = { id: string, author: string, created_at: number, kind: number, tags: Array<Array<string>>, content: string, sig: string, };
+
+export type RadrootsNostrEventPtr = { id: string, relays?: string | null, };
+
+export type RadrootsNostrEventRef = { id: string, author: string, kind: number, d_tag?: string | null, relays?: string[] | null, };
+
+export type RadrootsPlot = { d_tag: string, farm: RadrootsFarmRef, name: string, about?: string | null, location?: RadrootsPlotLocation | null, tags?: string[] | null, };
+
+export type RadrootsPlotLocation = { primary?: string | null, city?: string | null, region?: string | null, country?: string | null, gcs: RadrootsGcsLocation, };
+
+export type RadrootsPlotRef = { pubkey: string, d_tag: string, };
+
+export type RadrootsPost = { content: string, };
+
+export type RadrootsProfile = { name: string, display_name?: string | null, nip05?: string | null, about?: string | null, website?: string | null, picture?: string | null, banner?: string | null, lud06?: string | null, lud16?: string | null, bot?: string | null, };
+
+export type RadrootsProfileType = "individual" | "farm" | "coop" | "any" | "radrootsd";
+
+export type RadrootsReaction = { root: RadrootsNostrEventRef, content: string, };
+
+export type RadrootsRelayDocument = { name?: string | null, description?: string | null, pubkey?: string | null, contact?: string | null, supported_nips?: number[] | null, software?: string | null, version?: string | null, };
+
+export type RadrootsResourceArea = { d_tag: string, name: string, about?: string | null, location: RadrootsResourceAreaLocation, tags?: string[] | null, };
+
+export type RadrootsResourceAreaLocation = { primary?: string | null, city?: string | null, region?: string | null, country?: string | null, gcs: RadrootsGcsLocation, };
+
+export type RadrootsResourceAreaRef = { pubkey: string, d_tag: string, };
+
+export type RadrootsResourceHarvestCap = { d_tag: string, resource_area: RadrootsResourceAreaRef, product: RadrootsResourceHarvestProduct, start: bigint, end: bigint, cap_quantity: RadrootsCoreQuantity, display_amount?: RadrootsCoreDecimal | null, display_unit?: RadrootsCoreUnit | null, display_label?: string | null, tags?: string[] | null, };
+
+export type RadrootsResourceHarvestProduct = { key: string, category?: string | null, };
+
+export type RadrootsSeal = { content: string, };
+
+export type RadrootsTradeAnswer = { question_id: string, };
+
+export type RadrootsTradeBuyerReceipt = { order_id: string, listing_addr: string, buyer_pubkey: string, seller_pubkey: string, received: boolean, issue?: string | null, received_at: bigint, };
+
+export type RadrootsTradeDiscountDecision = { "kind": "accept", "amount": { value: RadrootsCoreDiscountValue, } } | { "kind": "decline", "amount": { reason?: string | null, } };
+
+export type RadrootsTradeDiscountOffer = { discount_id: string, value: RadrootsCoreDiscountValue, };
+
+export type RadrootsTradeDiscountRequest = { discount_id: string, value: RadrootsCoreDiscountValue, };
+
+export type RadrootsTradeDomain = "trade:listing";
+
+export type RadrootsTradeEconomicActor = "buyer" | "seller";
+
+export type RadrootsTradeEconomicEffect = "increase" | "decrease";
+
+export type RadrootsTradeEconomicLineKind = "listing_discount" | "basket_adjustment" | "revision_adjustment";
+
+export type RadrootsTradeEnvelope<T> = { version: number, domain: RadrootsTradeDomain, type: RadrootsTradeMessageType, order_id?: string | null, listing_addr: string, payload: T, };
+
+export type RadrootsTradeFulfillmentStatus = { "kind": "preparing" } | { "kind": "shipped" } | { "kind": "ready_for_pickup" } | { "kind": "delivered" } | { "kind": "cancelled" };
+
+export type RadrootsTradeFulfillmentUpdate = { status: RadrootsTradeFulfillmentStatus, };
+
+export type RadrootsTradeFulfillmentUpdated = { order_id: string, listing_addr: string, buyer_pubkey: string, seller_pubkey: string, status: RadrootsActiveTradeFulfillmentState, };
+
+export type RadrootsTradeInventoryCommitment = { bin_id: string, bin_count: number, };
+
+export type RadrootsTradeListingCancel = { reason?: string | null, };
+
+export type RadrootsTradeListingParseError = { "InvalidKind": number } | { "MissingTag": string } | { "InvalidTag": string } | { "InvalidNumber": string } | "InvalidUnit" | "InvalidCurrency" | { "InvalidJson": string } | { "InvalidDiscount": string };
+
+export type RadrootsTradeListingValidateRequest = { listing_event?: RadrootsNostrEventPtr | null, };
+
+export type RadrootsTradeListingValidateResult = { valid: boolean, errors: RadrootsTradeListingValidationError[], };
+
+export type RadrootsTradeListingValidationError = { "kind": "invalid_kind", "amount": { kind: number, } } | { "kind": "missing_listing_id" } | { "kind": "listing_event_not_found", "amount": { listing_addr: string, } } | { "kind": "listing_event_fetch_failed", "amount": { listing_addr: string, } } | { "kind": "parse_error", "amount": { error: RadrootsTradeListingParseError, } } | { "kind": "invalid_seller" } | { "kind": "missing_farm_profile" } | { "kind": "missing_farm_record" } | { "kind": "missing_title" } | { "kind": "missing_description" } | { "kind": "missing_product_type" } | { "kind": "missing_bins" } | { "kind": "missing_primary_bin" } | { "kind": "invalid_bin" } | { "kind": "missing_price" } | { "kind": "invalid_price" } | { "kind": "missing_inventory" } | { "kind": "invalid_inventory" } | { "kind": "missing_availability" } | { "kind": "missing_location" } | { "kind": "missing_delivery_method" };
+
+export type RadrootsTradeMessagePayload = { "kind": "listing_validate_request", "amount": RadrootsTradeListingValidateRequest } | { "kind": "listing_validate_result", "amount": RadrootsTradeListingValidateResult } | { "kind": "trade_order_requested", "amount": RadrootsTradeOrderRequested } | { "kind": "order_response", "amount": RadrootsTradeOrderResponse } | { "kind": "order_revision", "amount": RadrootsTradeOrderRevision } | { "kind": "order_revision_accept", "amount": RadrootsTradeOrderRevisionResponse } | { "kind": "order_revision_decline", "amount": RadrootsTradeOrderRevisionResponse } | { "kind": "question", "amount": RadrootsTradeQuestion } | { "kind": "answer", "amount": RadrootsTradeAnswer } | { "kind": "discount_request", "amount": RadrootsTradeDiscountRequest } | { "kind": "discount_offer", "amount": RadrootsTradeDiscountOffer } | { "kind": "discount_accept", "amount": RadrootsTradeDiscountDecision } | { "kind": "discount_decline", "amount": RadrootsTradeDiscountDecision } | { "kind": "cancel", "amount": RadrootsTradeListingCancel } | { "kind": "fulfillment_update", "amount": RadrootsTradeFulfillmentUpdate } | { "kind": "receipt", "amount": RadrootsTradeReceipt };
+
+export type RadrootsTradeMessageType = "listing_validate_request" | "listing_validate_result" | "order_request" | "order_response" | "order_revision" | "order_revision_accept" | "order_revision_decline" | "question" | "answer" | "discount_request" | "discount_offer" | "discount_accept" | "discount_decline" | "cancel" | "fulfillment_update" | "receipt";
+
+export type RadrootsTradeOrderCancelled = { order_id: string, listing_addr: string, buyer_pubkey: string, seller_pubkey: string, reason: string, };
+
+export type RadrootsTradeOrderChange = { "kind": "bin_count", "amount": { item_index: number, bin_count: number, } } | { "kind": "item_add", "amount": { item: RadrootsTradeOrderItem, } } | { "kind": "item_remove", "amount": { item_index: number, } };
+
+export type RadrootsTradeOrderDecision = { "decision": "accepted", inventory_commitments: Array<RadrootsTradeInventoryCommitment>, } | { "decision": "declined", reason: string, };
+
+export type RadrootsTradeOrderDecisionEvent = { order_id: string, listing_addr: string, buyer_pubkey: string, seller_pubkey: string, decision: RadrootsTradeOrderDecision, };
+
+export type RadrootsTradeOrderEconomicItem = { bin_id: string, bin_count: number, quantity_amount: RadrootsCoreDecimal, quantity_unit: RadrootsCoreUnit, unit_price_amount: RadrootsCoreDecimal, unit_price_currency: RadrootsCoreCurrency, line_subtotal: RadrootsCoreMoney, };
+
+export type RadrootsTradeOrderEconomicLine = { id: string, kind: RadrootsTradeEconomicLineKind, actor: RadrootsTradeEconomicActor, effect: RadrootsTradeEconomicEffect, amount: RadrootsCoreMoney, reason: string, };
+
+export type RadrootsTradeOrderEconomicTotals = { subtotal: RadrootsCoreMoney, discount_total: RadrootsCoreMoney, adjustment_total: RadrootsCoreMoney, total: RadrootsCoreMoney, };
+
+export type RadrootsTradeOrderEconomics = { quote_id: string, quote_version: number, pricing_basis: RadrootsTradePricingBasis, currency: RadrootsCoreCurrency, items: Array<RadrootsTradeOrderEconomicItem>, discounts: Array<RadrootsTradeOrderEconomicLine>, adjustments: Array<RadrootsTradeOrderEconomicLine>, subtotal: RadrootsCoreMoney, discount_total: RadrootsCoreMoney, adjustment_total: RadrootsCoreMoney, total: RadrootsCoreMoney, };
+
+export type RadrootsTradeOrderItem = { bin_id: string, bin_count: number, };
+
+export type RadrootsTradeOrderRequested = { order_id: string, listing_addr: string, buyer_pubkey: string, seller_pubkey: string, items: Array<RadrootsTradeOrderItem>, economics: RadrootsTradeOrderEconomics, };
+
+export type RadrootsTradeOrderResponse = { accepted: boolean, reason?: string | null, };
+
+export type RadrootsTradeOrderRevision = { revision_id: string, changes: Array<RadrootsTradeOrderChange>, };
+
+export type RadrootsTradeOrderRevisionDecision = { "decision": "accepted" } | { "decision": "declined", reason: string, };
+
+export type RadrootsTradeOrderRevisionDecisionEvent = { revision_id: string, order_id: string, listing_addr: string, buyer_pubkey: string, seller_pubkey: string, root_event_id: string, prev_event_id: string, decision: RadrootsTradeOrderRevisionDecision, };
+
+export type RadrootsTradeOrderRevisionProposed = { revision_id: string, order_id: string, listing_addr: string, buyer_pubkey: string, seller_pubkey: string, root_event_id: string, prev_event_id: string, items: Array<RadrootsTradeOrderItem>, economics: RadrootsTradeOrderEconomics, reason: string, };
+
+export type RadrootsTradeOrderRevisionResponse = { accepted: boolean, reason?: string | null, };
+
+export type RadrootsTradeOrderStatus = "draft" | "validated" | "requested" | "questioned" | "revised" | "accepted" | "declined" | "cancelled" | "fulfilled" | "completed";
+
+export type RadrootsTradePaymentMethod = "cash" | "manual_transfer" | "other";
+
+export type RadrootsTradePaymentRecorded = { order_id: string, listing_addr: string, buyer_pubkey: string, seller_pubkey: string, root_event_id: string, previous_event_id: string, agreement_event_id: string, quote_id: string, quote_version: number, economics_digest: string, amount: RadrootsCoreDecimal, currency: RadrootsCoreCurrency, method: RadrootsTradePaymentMethod, reference?: string | null, paid_at?: number | null, };
+
+export type RadrootsTradePricingBasis = "listing_event";
+
+export type RadrootsTradeQuestion = { question_id: string, };
+
+export type RadrootsTradeReceipt = { acknowledged: boolean, at: bigint, };
+
+export type RadrootsTradeSettlementDecision = "accepted" | "rejected";
+
+export type RadrootsTradeSettlementDecisionEvent = { order_id: string, listing_addr: string, seller_pubkey: string, buyer_pubkey: string, root_event_id: string, previous_event_id: string, agreement_event_id: string, payment_event_id: string, quote_id: string, quote_version: number, economics_digest: string, amount: RadrootsCoreDecimal, currency: RadrootsCoreCurrency, decision: RadrootsTradeSettlementDecision, reason?: string | null, };
+
+export type RadrootsTradeTransportLane = "service" | "public";
diff --git a/packages/events-bindings/src/index.ts b/packages/events-bindings/src/index.ts
@@ -1 +1,3 @@
-export {};
+export * from "./generated/types.js";
+export * from "./generated/constants.js";
+export * from "./generated/kinds.js";