@ixo/editor 3.9.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,8 +15,16 @@ var ACTION_TYPE_ALIASES = {
15
15
  "proposal.vote": "qi/proposal.vote",
16
16
  "protocol.select": "qi/protocol.select",
17
17
  "domain.sign": "qi/domain.sign",
18
- "domain.create": "qi/domain.create",
18
+ "domain.card-build": "qi/domain.card-build",
19
+ "domain.card-preview": "qi/domain.card-preview",
19
20
  "credential.store": "qi/credential.store",
21
+ // POD setup flow — camelCase orchestrator labels → canonical action types
22
+ DomainIndexerLookup: "qi/pod.domain-indexer-lookup",
23
+ DomainSingleSelection: "qi/pod.domain-single-selection",
24
+ EntitySingleSelection: "qi/pod.entity-single-selection",
25
+ MemberMultiSelect: "qi/pod.member-multi-select",
26
+ governanceConfig: "qi/pod.governance-config",
27
+ listDomainFlows: "qi/pod.list-domain-flows",
20
28
  payment: "qi/payment.execute",
21
29
  "matrix.dm": "qi/matrix.dm"
22
30
  };
@@ -54,7 +62,8 @@ var CAN_TO_TYPE = {
54
62
  "matrix/dm": "qi/matrix.dm",
55
63
  "proposal/create": "qi/proposal.create",
56
64
  "proposal/vote": "qi/proposal.vote",
57
- "domain/create": "qi/domain.create",
65
+ "domain/card-build": "qi/domain.card-build",
66
+ "domain/card-preview": "qi/domain.card-preview",
58
67
  "domain/sign": "qi/domain.sign",
59
68
  "credential/store": "qi/credential.store",
60
69
  "payment/execute": "qi/payment.execute",
@@ -347,10 +356,13 @@ registerAction({
347
356
  sideEffect: false,
348
357
  defaultRequiresConfirmation: false,
349
358
  outputSchema: [
359
+ { path: "groupName", displayName: "Group Name", type: "string", description: "Human-readable name for the governance group" },
350
360
  { path: "groupType", displayName: "Group Type", type: "string", description: "Governance group type (categorical | multisig | nftStaking | tokenStaking)" },
351
361
  { path: "governance", displayName: "Governance Settings", type: "object", description: "Cosmos group decision policy parameters" }
352
362
  ],
353
363
  run: async (inputs) => {
364
+ const groupName = String(inputs.groupName || "").trim();
365
+ if (!groupName) throw new Error("groupName is required");
354
366
  const groupType = inputs.groupType;
355
367
  if (!groupType || !VALID_GROUP_TYPES.includes(groupType)) {
356
368
  throw new Error(`groupType must be one of: ${VALID_GROUP_TYPES.join(", ")}`);
@@ -359,8 +371,11 @@ registerAction({
359
371
  if (!governance) throw new Error("governance settings are required");
360
372
  if (!governance.votingPeriod) throw new Error("votingPeriod is required");
361
373
  if (groupType === "multisig") {
362
- const threshold = parseInt(governance.threshold, 10);
363
- if (isNaN(threshold) || threshold < 1) throw new Error("multisig threshold must be a positive integer");
374
+ const raw = String(governance.threshold ?? "").trim();
375
+ const threshold = Number(raw);
376
+ if (!raw || !Number.isFinite(threshold) || !Number.isInteger(threshold) || threshold < 1) {
377
+ throw new Error("multisig threshold must be a positive integer");
378
+ }
364
379
  } else {
365
380
  const quorum = parseFloat(governance.quorum);
366
381
  if (isNaN(quorum) || quorum <= 0 || quorum > 1) throw new Error("quorum must be between 0 and 1 (e.g. 0.33)");
@@ -371,7 +386,7 @@ registerAction({
371
386
  throw new Error("threshold + vetoThreshold cannot exceed 1.0");
372
387
  }
373
388
  }
374
- return { output: { groupType, governance } };
389
+ return { output: { groupName, groupType, governance } };
375
390
  }
376
391
  });
377
392
 
@@ -1169,211 +1184,7 @@ registerAction({
1169
1184
  }
1170
1185
  });
1171
1186
 
1172
- // src/mantine/blocks/domainCreator/utils/buildVerifiableCredential.ts
1173
- var DOMAIN_CARD_CONTEXT = [
1174
- "https://w3id.org/ixo/context/v1",
1175
- {
1176
- schema: "https://schema.org/",
1177
- ixo: "https://w3id.org/ixo/vocab/v1",
1178
- prov: "http://www.w3.org/ns/prov#",
1179
- proj: "http://www.w3.org/ns/project#",
1180
- id: "@id",
1181
- type: "@type",
1182
- "@protected": true
1183
- }
1184
- ];
1185
- var DOMAIN_CARD_SCHEMA = {
1186
- id: "https://w3id.org/ixo/protocol/schema/v1#domainCard",
1187
- type: "JsonSchema"
1188
- };
1189
- function toISOString(dateInput, fallback = /* @__PURE__ */ new Date()) {
1190
- if (!dateInput) {
1191
- return fallback.toISOString();
1192
- }
1193
- if (dateInput instanceof Date) {
1194
- return dateInput.toISOString();
1195
- }
1196
- if (/^\d{4}-\d{2}-\d{2}$/.test(dateInput)) {
1197
- return (/* @__PURE__ */ new Date(dateInput + "T00:00:00.000Z")).toISOString();
1198
- }
1199
- if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(dateInput)) {
1200
- return (/* @__PURE__ */ new Date(dateInput + ":00.000Z")).toISOString();
1201
- }
1202
- const parsed = new Date(dateInput);
1203
- if (!isNaN(parsed.getTime())) {
1204
- return parsed.toISOString();
1205
- }
1206
- return fallback.toISOString();
1207
- }
1208
- function getDefaultValidUntil(validFrom) {
1209
- const fromDate = new Date(validFrom);
1210
- const untilDate = new Date(fromDate);
1211
- untilDate.setFullYear(untilDate.getFullYear() + 5);
1212
- return untilDate.toISOString();
1213
- }
1214
- function buildVerifiableCredential(params) {
1215
- const { entityDid, issuerDid, credentialSubject, validFrom, validUntil } = params;
1216
- const validFromISO = toISOString(validFrom);
1217
- const validUntilISO = validUntil ? toISOString(validUntil) : getDefaultValidUntil(validFromISO);
1218
- return {
1219
- "@context": DOMAIN_CARD_CONTEXT,
1220
- id: `${entityDid}#dmn`,
1221
- type: ["VerifiableCredential", "ixo:DomainCard"],
1222
- issuer: {
1223
- id: issuerDid
1224
- },
1225
- validFrom: validFromISO,
1226
- validUntil: validUntilISO,
1227
- credentialSchema: DOMAIN_CARD_SCHEMA,
1228
- credentialSubject: {
1229
- ...credentialSubject,
1230
- // Ensure the subject ID matches the entity DID
1231
- id: entityDid
1232
- }
1233
- };
1234
- }
1235
- function buildDomainCardLinkedResource(params) {
1236
- return {
1237
- id: `${params.entityDid}#dmn`,
1238
- type: "domainCard",
1239
- proof: params.cid,
1240
- right: "",
1241
- encrypted: "false",
1242
- mediaType: "application/json",
1243
- description: params.description || "Domain Card",
1244
- serviceEndpoint: params.serviceEndpoint
1245
- };
1246
- }
1247
-
1248
- // src/mantine/blocks/domainCreatorSign/utils/buildLinkedEntityResource.ts
1249
- function parseLinkedEntities(entitiesString) {
1250
- if (!entitiesString || entitiesString === "[]") return [];
1251
- try {
1252
- return JSON.parse(entitiesString);
1253
- } catch {
1254
- return [];
1255
- }
1256
- }
1257
- function buildGovernanceGroupLinkedEntities(linkedEntities) {
1258
- return linkedEntities.filter((entity) => entity.type === "governanceGroup" && entity.coreAddress).map((entity) => ({
1259
- id: entity.coreAddress,
1260
- type: "group",
1261
- relationship: "governs",
1262
- service: ""
1263
- }));
1264
- }
1265
-
1266
- // src/core/lib/actionRegistry/actions/domainSign.ts
1267
- registerAction({
1268
- type: "qi/domain.sign",
1269
- can: "domain/sign",
1270
- sideEffect: true,
1271
- defaultRequiresConfirmation: true,
1272
- requiredCapability: "flow/block/execute",
1273
- outputSchema: [
1274
- { path: "entityDid", displayName: "Entity DID", type: "string", description: "The DID of the newly created domain entity" },
1275
- { path: "transactionHash", displayName: "Transaction Hash", type: "string", description: "The on-chain transaction hash for domain creation" }
1276
- ],
1277
- run: async (inputs, ctx) => {
1278
- const handlers = ctx.handlers;
1279
- if (!handlers) {
1280
- throw new Error("Handlers not available");
1281
- }
1282
- if (!handlers.requestPin) throw new Error("requestPin handler not available");
1283
- if (!handlers.signCredential) throw new Error("signCredential handler not implemented");
1284
- if (!handlers.publicFileUpload) throw new Error("publicFileUpload handler not available");
1285
- if (!handlers.createDomain) throw new Error("createDomain handler not implemented");
1286
- let domainCardData;
1287
- if (typeof inputs.domainCardData === "string") {
1288
- try {
1289
- domainCardData = JSON.parse(inputs.domainCardData);
1290
- } catch {
1291
- throw new Error("domainCardData must be valid JSON");
1292
- }
1293
- } else if (inputs.domainCardData && typeof inputs.domainCardData === "object") {
1294
- domainCardData = inputs.domainCardData;
1295
- } else {
1296
- throw new Error("domainCardData is required");
1297
- }
1298
- if (!domainCardData?.credentialSubject?.name) {
1299
- throw new Error("domainCardData is missing or invalid (credentialSubject.name required)");
1300
- }
1301
- const extractEntityType = (type) => type.replace(/^schema:/i, "").toLowerCase();
1302
- const entityType = String(inputs.entityType || "").trim() || (domainCardData.credentialSubject?.type?.[0] ? extractEntityType(domainCardData.credentialSubject.type[0]) : "dao");
1303
- const issuerDid = handlers.getEntityDid?.() || handlers.getCurrentUser?.()?.address;
1304
- if (!issuerDid) throw new Error("Unable to determine issuer DID");
1305
- const entityDidPlaceholder = "did:ixo:entity:pending";
1306
- const validFrom = domainCardData.validFrom || (/* @__PURE__ */ new Date()).toISOString();
1307
- const validUntil = domainCardData.validUntil || (() => {
1308
- const d = /* @__PURE__ */ new Date();
1309
- d.setFullYear(d.getFullYear() + 100);
1310
- return d.toISOString();
1311
- })();
1312
- const credentialSubject = {
1313
- ...domainCardData.credentialSubject,
1314
- id: entityDidPlaceholder
1315
- };
1316
- const unsignedCredential = buildVerifiableCredential({
1317
- entityDid: entityDidPlaceholder,
1318
- issuerDid,
1319
- credentialSubject,
1320
- validFrom,
1321
- validUntil
1322
- });
1323
- const pin = await handlers.requestPin({
1324
- title: "Sign Domain Card",
1325
- description: "Enter your PIN to sign the Domain Card credential",
1326
- submitText: "Sign"
1327
- });
1328
- const { signedCredential } = await handlers.signCredential({
1329
- issuerDid,
1330
- issuerType: "user",
1331
- credential: unsignedCredential,
1332
- pin
1333
- });
1334
- const credentialBlob = new Blob([JSON.stringify(signedCredential, null, 2)], {
1335
- type: "application/json"
1336
- });
1337
- const credentialFile = new File([credentialBlob], "domainCard.json", {
1338
- type: "application/json"
1339
- });
1340
- const uploadResult = await handlers.publicFileUpload(credentialFile);
1341
- const domainCardLinkedResource = buildDomainCardLinkedResource({
1342
- entityDid: entityDidPlaceholder,
1343
- cid: uploadResult.cid,
1344
- serviceEndpoint: uploadResult.url,
1345
- description: `Domain Card for ${domainCardData.credentialSubject?.name || "Domain"}`
1346
- });
1347
- let linkedEntitiesData = [];
1348
- if (inputs.linkedEntities) {
1349
- if (typeof inputs.linkedEntities === "string") {
1350
- try {
1351
- linkedEntitiesData = JSON.parse(inputs.linkedEntities);
1352
- } catch {
1353
- }
1354
- } else if (Array.isArray(inputs.linkedEntities)) {
1355
- linkedEntitiesData = inputs.linkedEntities;
1356
- }
1357
- }
1358
- const governanceGroupLinkedEntities = buildGovernanceGroupLinkedEntities(parseLinkedEntities(JSON.stringify(linkedEntitiesData)));
1359
- const endDate = domainCardData.endDate || validUntil;
1360
- const { entityDid: newEntityDid, transactionHash } = await handlers.createDomain({
1361
- entityType,
1362
- linkedResource: [domainCardLinkedResource],
1363
- linkedEntity: governanceGroupLinkedEntities.length > 0 ? governanceGroupLinkedEntities : void 0,
1364
- startDate: validFrom,
1365
- endDate
1366
- });
1367
- return {
1368
- output: {
1369
- entityDid: newEntityDid,
1370
- transactionHash
1371
- }
1372
- };
1373
- }
1374
- });
1375
-
1376
- // src/mantine/blocks/domainCreator/utils/transformSurveyToCredentialSubject.ts
1187
+ // src/core/lib/domainCard/transformSurveyToCredentialSubject.ts
1377
1188
  function extractPanelDynamicItems(surveyData, panelName, itemMapper) {
1378
1189
  const items = surveyData[panelName];
1379
1190
  if (!Array.isArray(items)) return [];
@@ -1605,91 +1416,837 @@ function transformSurveyToCredentialSubject(surveyData, entityDid) {
1605
1416
  return credentialSubject;
1606
1417
  }
1607
1418
 
1608
- // src/mantine/blocks/domainCreator/utils/extractSurveyAnswersTemplate.ts
1609
- function extractFieldsFromElements(elements, fields) {
1610
- for (const element of elements) {
1611
- if (element.type === "panel" && element.elements) {
1612
- extractFieldsFromElements(element.elements, fields);
1613
- continue;
1614
- }
1615
- if (element.type === "paneldynamic" && element.name) {
1616
- fields[element.name] = [];
1617
- if (element.templateElements) {
1618
- extractFieldsFromElements(element.templateElements, fields);
1619
- }
1620
- continue;
1621
- }
1622
- if (element.name && element.type !== "panel") {
1623
- switch (element.type) {
1624
- case "boolean":
1625
- fields[element.name] = false;
1626
- break;
1627
- case "checkbox":
1628
- fields[element.name] = [];
1629
- break;
1630
- case "file":
1631
- fields[element.name] = [];
1632
- break;
1633
- default:
1634
- fields[element.name] = "";
1635
- }
1636
- }
1637
- if (element.elements) {
1638
- extractFieldsFromElements(element.elements, fields);
1639
- }
1419
+ // src/core/lib/domainCard/buildVerifiableCredential.ts
1420
+ var DOMAIN_CARD_CONTEXT = [
1421
+ "https://w3id.org/ixo/context/v1",
1422
+ {
1423
+ schema: "https://schema.org/",
1424
+ ixo: "https://w3id.org/ixo/vocab/v1",
1425
+ prov: "http://www.w3.org/ns/prov#",
1426
+ proj: "http://www.w3.org/ns/project#",
1427
+ id: "@id",
1428
+ type: "@type",
1429
+ "@protected": true
1640
1430
  }
1641
- }
1642
- function extractSurveyAnswersTemplate(surveyDef) {
1643
- const fields = {};
1644
- for (const page of surveyDef.pages) {
1645
- extractFieldsFromElements(page.elements, fields);
1431
+ ];
1432
+ var DOMAIN_CARD_SCHEMA = {
1433
+ id: "https://w3id.org/ixo/protocol/schema/v1#domainCard",
1434
+ type: "JsonSchema"
1435
+ };
1436
+ function toISOString(dateInput, fallback = /* @__PURE__ */ new Date()) {
1437
+ if (!dateInput) {
1438
+ return fallback.toISOString();
1439
+ }
1440
+ if (dateInput instanceof Date) {
1441
+ return dateInput.toISOString();
1442
+ }
1443
+ if (/^\d{4}-\d{2}-\d{2}$/.test(dateInput)) {
1444
+ return (/* @__PURE__ */ new Date(dateInput + "T00:00:00.000Z")).toISOString();
1445
+ }
1446
+ if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(dateInput)) {
1447
+ return (/* @__PURE__ */ new Date(dateInput + ":00.000Z")).toISOString();
1448
+ }
1449
+ const parsed = new Date(dateInput);
1450
+ if (!isNaN(parsed.getTime())) {
1451
+ return parsed.toISOString();
1646
1452
  }
1647
- return fields;
1453
+ return fallback.toISOString();
1648
1454
  }
1649
-
1650
- // src/core/lib/actionRegistry/actions/domainCreate.ts
1651
- registerAction({
1652
- type: "qi/domain.create",
1653
- can: "domain/create",
1654
- sideEffect: true,
1655
- defaultRequiresConfirmation: true,
1656
- requiredCapability: "flow/block/execute",
1657
- outputSchema: [
1658
- { path: "entityDid", displayName: "Entity DID", type: "string", description: "The created domain entity DID" },
1659
- { path: "transactionHash", displayName: "Transaction Hash", type: "string", description: "Blockchain transaction hash" },
1660
- { path: "credentialId", displayName: "Credential ID", type: "string", description: "The uploaded domain card credential identifier (CID)" },
1661
- { path: "entityType", displayName: "Entity Type", type: "string", description: "The type of domain entity created" }
1662
- ],
1663
- run: async (inputs, ctx) => {
1664
- const handlers = ctx.handlers;
1665
- if (!handlers) throw new Error("Handlers not available");
1666
- if (!handlers.signCredential) throw new Error("signCredential handler not implemented");
1667
- if (!handlers.publicFileUpload) throw new Error("publicFileUpload handler not available");
1668
- if (!handlers.createDomain) throw new Error("createDomain handler not implemented");
1669
- if (!handlers.requestPin) throw new Error("requestPin handler not available");
1670
- const configEntityType = String(inputs.entityType || "dao").trim();
1671
- let surveyData = {};
1672
- if (inputs.surveyData) {
1673
- if (typeof inputs.surveyData === "string") {
1674
- try {
1675
- surveyData = JSON.parse(inputs.surveyData);
1676
- } catch {
1677
- throw new Error("surveyData must be valid JSON");
1455
+ function getDefaultValidUntil(validFrom) {
1456
+ const fromDate = new Date(validFrom);
1457
+ const untilDate = new Date(fromDate);
1458
+ untilDate.setFullYear(untilDate.getFullYear() + 5);
1459
+ return untilDate.toISOString();
1460
+ }
1461
+ function buildVerifiableCredential(params) {
1462
+ const { entityDid, issuerDid, credentialSubject, validFrom, validUntil } = params;
1463
+ const validFromISO = toISOString(validFrom);
1464
+ const validUntilISO = validUntil ? toISOString(validUntil) : getDefaultValidUntil(validFromISO);
1465
+ return {
1466
+ "@context": DOMAIN_CARD_CONTEXT,
1467
+ id: `${entityDid}#dmn`,
1468
+ type: ["VerifiableCredential", "ixo:DomainCard"],
1469
+ issuer: {
1470
+ id: issuerDid
1471
+ },
1472
+ validFrom: validFromISO,
1473
+ validUntil: validUntilISO,
1474
+ credentialSchema: DOMAIN_CARD_SCHEMA,
1475
+ credentialSubject: {
1476
+ ...credentialSubject,
1477
+ // Ensure the subject ID matches the entity DID
1478
+ id: entityDid
1479
+ }
1480
+ };
1481
+ }
1482
+ function buildDomainCardLinkedResource(params) {
1483
+ return {
1484
+ id: `${params.entityDid}#dmn`,
1485
+ type: "domainCard",
1486
+ proof: params.cid,
1487
+ right: "",
1488
+ encrypted: "false",
1489
+ mediaType: "application/json",
1490
+ description: params.description || "Domain Card",
1491
+ serviceEndpoint: params.serviceEndpoint
1492
+ };
1493
+ }
1494
+
1495
+ // src/core/lib/domainCard/buildLinkedEntityResource.ts
1496
+ function parseLinkedEntities(entitiesString) {
1497
+ if (!entitiesString || entitiesString === "[]") return [];
1498
+ try {
1499
+ return JSON.parse(entitiesString);
1500
+ } catch {
1501
+ return [];
1502
+ }
1503
+ }
1504
+ function buildGovernanceGroupLinkedEntities(linkedEntities) {
1505
+ return linkedEntities.filter((entity) => entity.type === "governanceGroup" && entity.coreAddress).map((entity) => ({
1506
+ id: entity.coreAddress,
1507
+ type: "group",
1508
+ relationship: "governs",
1509
+ service: ""
1510
+ }));
1511
+ }
1512
+
1513
+ // src/core/lib/domainCard/defaultSurvey.ts
1514
+ var tempDomainCreatorSurvey = {
1515
+ title: "Domain Card Creation",
1516
+ description: "This survey collects structured information required to create a Domain Card Verifiable Credential in compliance with W3C standards.",
1517
+ pages: [
1518
+ {
1519
+ name: "domainDetails",
1520
+ title: "Domain Information",
1521
+ description: "Provide identifying and descriptive information about the domain entity represented by this credential.",
1522
+ elements: [
1523
+ {
1524
+ type: "boolean",
1525
+ name: "ixo:advancedDomainSettings",
1526
+ title: "Show Advanced Options",
1527
+ defaultValue: "false"
1528
+ },
1529
+ {
1530
+ type: "dropdown",
1531
+ name: "type_1",
1532
+ visible: false,
1533
+ title: "Domain Type (Primary)",
1534
+ defaultValue: "dao",
1535
+ choices: [
1536
+ {
1537
+ value: "dao",
1538
+ text: "DAO"
1539
+ },
1540
+ {
1541
+ value: "protocol",
1542
+ text: "Protocol"
1543
+ }
1544
+ ]
1545
+ },
1546
+ {
1547
+ type: "dropdown",
1548
+ name: "type_2",
1549
+ title: "Domain Type ",
1550
+ isRequired: true,
1551
+ choicesByUrl: {
1552
+ url: "https://test.studio.ixo.earth/api/survey-choices?url=https://raw.githubusercontent.com/ixofoundation/ns/refs/heads/GraemeLeightonIXO-patch-4/protocol/entities/v1/index.json&path=entities.dao.types",
1553
+ valueName: "Value",
1554
+ titleName: "Text"
1555
+ }
1556
+ },
1557
+ {
1558
+ type: "dropdown",
1559
+ name: "daoType",
1560
+ title: "DAO Type",
1561
+ isRequired: true,
1562
+ choicesByUrl: {
1563
+ url: "https://test.studio.ixo.earth/api/survey-choices?url=https://raw.githubusercontent.com/ixofoundation/ns/refs/heads/GraemeLeightonIXO-patch-4/protocol/tags/v1/index.json&path=daoType",
1564
+ valueName: "Value",
1565
+ titleName: "Text"
1566
+ }
1567
+ },
1568
+ {
1569
+ type: "text",
1570
+ name: "schema:validFrom",
1571
+ title: "Valid From",
1572
+ defaultValueExpression: "today()",
1573
+ isRequired: true,
1574
+ inputType: "date"
1575
+ },
1576
+ {
1577
+ type: "text",
1578
+ name: "schema:validUntil",
1579
+ title: "Vaid Untill",
1580
+ defaultValueExpression: "today()",
1581
+ isRequired: true,
1582
+ inputType: "date"
1583
+ },
1584
+ {
1585
+ type: "text",
1586
+ name: "schema:name",
1587
+ title: "Domain Name",
1588
+ description: "The official name of the domain.",
1589
+ isRequired: true
1590
+ },
1591
+ {
1592
+ type: "paneldynamic",
1593
+ name: "pannel_schema:alternateName",
1594
+ title: "Alternate Names",
1595
+ templateElements: [
1596
+ {
1597
+ type: "text",
1598
+ name: "schema:alternateName",
1599
+ title: "Alternate Name"
1600
+ }
1601
+ ]
1602
+ },
1603
+ {
1604
+ type: "text",
1605
+ name: "schema:url",
1606
+ title: "URL",
1607
+ description: "Primary URL for the domain",
1608
+ inputType: "url"
1609
+ },
1610
+ {
1611
+ type: "paneldynamic",
1612
+ name: "schema:sameAs",
1613
+ title: "Additional URLs",
1614
+ description: "Additional URLs associated with the domain (Twitter, Github, Medium)",
1615
+ templateElements: [
1616
+ {
1617
+ type: "text",
1618
+ name: "schema:sameAs.url",
1619
+ title: "URL",
1620
+ inputType: "url"
1621
+ }
1622
+ ]
1623
+ },
1624
+ {
1625
+ type: "comment",
1626
+ name: "schema.description",
1627
+ title: "Canonical Description",
1628
+ description: "A concise, one-paragraph description of the domain.",
1629
+ isRequired: true
1630
+ },
1631
+ {
1632
+ type: "panel",
1633
+ name: "pannel_schema:media",
1634
+ title: "Domain Images",
1635
+ elements: [
1636
+ {
1637
+ type: "text",
1638
+ name: "ixo:imageProfile_url",
1639
+ title: "Profile Image URL",
1640
+ inputType: "url"
1641
+ },
1642
+ {
1643
+ type: "file",
1644
+ name: "ixo:imageProfile",
1645
+ title: "Profile Image"
1646
+ },
1647
+ {
1648
+ type: "text",
1649
+ name: "ixo:imageLogo_url",
1650
+ title: "Logo URL",
1651
+ inputType: "url"
1652
+ },
1653
+ {
1654
+ type: "file",
1655
+ name: "ixo:imageLogo",
1656
+ title: "Logo"
1657
+ }
1658
+ ]
1659
+ },
1660
+ {
1661
+ type: "comment",
1662
+ name: "schema:keywords",
1663
+ title: "Keywords",
1664
+ description: "List of comma separated keywords describing the domain\u2019s focus areas."
1665
+ },
1666
+ {
1667
+ type: "paneldynamic",
1668
+ name: "pannel_ixo:knowsAbout",
1669
+ title: "Topics /Primary Knowledge Areas",
1670
+ description: "Subjects or fields the domain is knowledgeable in.",
1671
+ templateElements: [
1672
+ {
1673
+ type: "text",
1674
+ name: "ixo:knowsAbout",
1675
+ title: "Knows About"
1676
+ }
1677
+ ]
1678
1678
  }
1679
- } else if (typeof inputs.surveyData === "object" && !Array.isArray(inputs.surveyData)) {
1680
- surveyData = inputs.surveyData;
1679
+ ]
1680
+ },
1681
+ {
1682
+ name: "contactAndLocation",
1683
+ visibleIf: "{ixo:advancedDomainSettings} = true",
1684
+ title: "Contact & Location",
1685
+ description: "Provide address and contact information for the domain.",
1686
+ elements: [
1687
+ {
1688
+ type: "panel",
1689
+ name: "schema:address",
1690
+ title: "Postal Address",
1691
+ elements: [
1692
+ {
1693
+ type: "text",
1694
+ name: "schema:streetAddress",
1695
+ title: "Street Address"
1696
+ },
1697
+ {
1698
+ type: "text",
1699
+ name: "schema:addressLocality",
1700
+ title: "City"
1701
+ },
1702
+ {
1703
+ type: "text",
1704
+ name: "schema:addressRegion",
1705
+ title: "Region/State"
1706
+ },
1707
+ {
1708
+ type: "text",
1709
+ name: "schema:postalCode",
1710
+ title: "Postal Code"
1711
+ },
1712
+ {
1713
+ type: "text",
1714
+ name: "schema:addressCountry",
1715
+ title: "Country"
1716
+ }
1717
+ ]
1718
+ },
1719
+ {
1720
+ type: "text",
1721
+ name: "schema:AdministrativeArea",
1722
+ title: "Area Served"
1723
+ },
1724
+ {
1725
+ type: "paneldynamic",
1726
+ name: "pannel:schema_contactPoint",
1727
+ title: "Contact Points",
1728
+ description: "List available contact methods for support, business, or technical inquiries.",
1729
+ templateElements: [
1730
+ {
1731
+ type: "text",
1732
+ name: "schema:contactType",
1733
+ title: "Contact Type",
1734
+ description: "Example: General, Support, Sales"
1735
+ },
1736
+ {
1737
+ type: "text",
1738
+ name: "schema:email",
1739
+ title: "Email Address",
1740
+ inputType: "email"
1741
+ },
1742
+ {
1743
+ type: "text",
1744
+ name: "schema:telephone",
1745
+ title: "Telephone ",
1746
+ inputType: "tel"
1747
+ },
1748
+ {
1749
+ type: "text",
1750
+ name: "schema:availableLanguage",
1751
+ title: "Languages Supported",
1752
+ description: "Comma separated two letter language code (English = en)"
1753
+ }
1754
+ ]
1755
+ }
1756
+ ]
1757
+ },
1758
+ {
1759
+ name: "composition",
1760
+ visibleIf: "{ixo:advancedDomainSettings} = true",
1761
+ title: "Composition",
1762
+ elements: [
1763
+ {
1764
+ type: "paneldynamic",
1765
+ name: "schema:hasPart",
1766
+ title: "Domain Components",
1767
+ description: "Describes the specific items, documents, linked domains, or components that belong to this domain.",
1768
+ templateElements: [
1769
+ {
1770
+ type: "text",
1771
+ name: "schema:hasPart.id",
1772
+ title: "Identifier",
1773
+ description: "URI or URL "
1774
+ },
1775
+ {
1776
+ type: "text",
1777
+ name: "schema:hasPart.name",
1778
+ title: "Name"
1779
+ },
1780
+ {
1781
+ type: "text",
1782
+ name: "schema:hasPart.description",
1783
+ title: "Description"
1784
+ },
1785
+ {
1786
+ type: "text",
1787
+ name: "schema:hasPart.url",
1788
+ title: "URL",
1789
+ description: "If different to the identifier",
1790
+ inputType: "url"
1791
+ },
1792
+ {
1793
+ type: "text",
1794
+ name: "schema:hasPart.creator.name",
1795
+ title: "Creator",
1796
+ description: "Component creator (Organisation Name)"
1797
+ }
1798
+ ]
1799
+ },
1800
+ {
1801
+ type: "paneldynamic",
1802
+ name: "schema:subjectOf",
1803
+ title: "Publications",
1804
+ description: "Publications produced by the domain or where the domain is the subject.",
1805
+ templateElements: [
1806
+ {
1807
+ type: "text",
1808
+ name: "schema:subjectOf.name",
1809
+ title: "Publication Title"
1810
+ },
1811
+ {
1812
+ type: "text",
1813
+ name: "schema:subjectOf.url",
1814
+ title: "URL"
1815
+ },
1816
+ {
1817
+ type: "text",
1818
+ name: "schema:subjectOf.author.name",
1819
+ title: "Author"
1820
+ }
1821
+ ]
1822
+ },
1823
+ {
1824
+ type: "paneldynamic",
1825
+ name: "schema:makesOffer",
1826
+ title: "Offers (Product and/or Services)",
1827
+ templateElements: [
1828
+ {
1829
+ type: "dropdown",
1830
+ name: "schema:itemOffered.type",
1831
+ title: "Catagory",
1832
+ choices: [
1833
+ {
1834
+ value: "product",
1835
+ text: "Product"
1836
+ },
1837
+ {
1838
+ value: "service",
1839
+ text: "Service"
1840
+ }
1841
+ ]
1842
+ },
1843
+ {
1844
+ type: "text",
1845
+ name: "schema:itemOffered.name",
1846
+ title: "Name"
1847
+ },
1848
+ {
1849
+ type: "text",
1850
+ name: "schema:itemOffered.description",
1851
+ title: "Description"
1852
+ },
1853
+ {
1854
+ type: "text",
1855
+ name: "schema:itemOffered.url",
1856
+ title: "URL",
1857
+ inputType: "url"
1858
+ }
1859
+ ]
1860
+ }
1861
+ ]
1862
+ },
1863
+ {
1864
+ name: "relationshipsAndOffers",
1865
+ visibleIf: "{ixo:advancedDomainSettings} = true",
1866
+ title: "Relationships & Funding",
1867
+ description: "Describe the domain\u2019s relationships with other organizations and its software or service offerings.",
1868
+ elements: [
1869
+ {
1870
+ type: "paneldynamic",
1871
+ name: "schema:memberOf",
1872
+ title: "Memberships",
1873
+ templateElements: [
1874
+ {
1875
+ type: "text",
1876
+ name: "schema:memberOf.name",
1877
+ title: "Organization Name"
1878
+ }
1879
+ ]
1880
+ },
1881
+ {
1882
+ type: "paneldynamic",
1883
+ name: "schema:wasAssociatedWith",
1884
+ title: "Partner/Associated Organizations",
1885
+ templateElements: [
1886
+ {
1887
+ type: "text",
1888
+ name: "schema:wasAssociatedWith.name",
1889
+ title: "Organization Name"
1890
+ },
1891
+ {
1892
+ type: "text",
1893
+ name: "schema:wasAssociatedWith.url",
1894
+ title: "URL"
1895
+ }
1896
+ ]
1897
+ },
1898
+ {
1899
+ type: "paneldynamic",
1900
+ name: "schema:funding",
1901
+ title: "Funding Sources",
1902
+ templateElements: [
1903
+ {
1904
+ type: "text",
1905
+ name: "schema:funder.name",
1906
+ title: "Funder Organization"
1907
+ },
1908
+ {
1909
+ type: "text",
1910
+ name: "schema:amount.currency",
1911
+ title: "Currency Code"
1912
+ },
1913
+ {
1914
+ type: "text",
1915
+ name: "schema:amount.value",
1916
+ title: "Funding Amount"
1917
+ }
1918
+ ]
1919
+ }
1920
+ ]
1921
+ },
1922
+ {
1923
+ name: "events",
1924
+ visibleIf: "{ixo:advancedDomainSettings} = true",
1925
+ title: "Events",
1926
+ elements: [
1927
+ {
1928
+ type: "paneldynamic",
1929
+ name: "schema:event",
1930
+ title: "Event",
1931
+ templateElements: [
1932
+ {
1933
+ type: "text",
1934
+ name: "schema:event.name",
1935
+ title: "Name"
1936
+ },
1937
+ {
1938
+ type: "text",
1939
+ name: "schema:startDate",
1940
+ title: "Start Date"
1941
+ },
1942
+ {
1943
+ type: "text",
1944
+ name: "schema:endDate",
1945
+ title: "End Date"
1946
+ },
1947
+ {
1948
+ type: "text",
1949
+ name: "schema:event.location",
1950
+ title: "Location Name"
1951
+ },
1952
+ {
1953
+ type: "panel",
1954
+ name: "schema:event.address",
1955
+ title: "Postal Address",
1956
+ elements: [
1957
+ {
1958
+ type: "text",
1959
+ name: "schema:event.streetAddress",
1960
+ title: "Street Address"
1961
+ },
1962
+ {
1963
+ type: "text",
1964
+ name: "schema:event.addressLocality",
1965
+ title: "City"
1966
+ },
1967
+ {
1968
+ type: "text",
1969
+ name: "schema:event.addressRegion",
1970
+ title: "Region/State"
1971
+ },
1972
+ {
1973
+ type: "text",
1974
+ name: "schema:event.postalCode",
1975
+ title: "Postal Code"
1976
+ },
1977
+ {
1978
+ type: "text",
1979
+ name: "schema:event.addressCountry",
1980
+ title: "Country"
1981
+ }
1982
+ ]
1983
+ }
1984
+ ]
1985
+ }
1986
+ ]
1987
+ },
1988
+ {
1989
+ name: "agentsCredentialsAndAttributes",
1990
+ visibleIf: "{ixo:advancedDomainSettings} = true",
1991
+ title: "Agents, Credentials, and Attributes",
1992
+ elements: [
1993
+ {
1994
+ type: "paneldynamic",
1995
+ name: "ixo:agentCard",
1996
+ title: "Agents",
1997
+ templateElements: [
1998
+ {
1999
+ type: "text",
2000
+ name: "ixo:agentCard.id",
2001
+ title: "Agent ID"
2002
+ },
2003
+ {
2004
+ type: "text",
2005
+ name: "ixo:agentCard.name",
2006
+ title: "Name"
2007
+ },
2008
+ {
2009
+ type: "text",
2010
+ name: "ixo:agentCard.description",
2011
+ title: "Description"
2012
+ }
2013
+ ]
2014
+ },
2015
+ {
2016
+ type: "paneldynamic",
2017
+ name: "ixo:verifiableCredential",
2018
+ title: "Credentials",
2019
+ templateElements: [
2020
+ {
2021
+ type: "text",
2022
+ name: "schema:ID",
2023
+ title: "Credential ID"
2024
+ },
2025
+ {
2026
+ type: "text",
2027
+ name: "schema:Name",
2028
+ title: "Name"
2029
+ },
2030
+ {
2031
+ type: "text",
2032
+ name: "schema:description",
2033
+ title: "Description"
2034
+ }
2035
+ ]
2036
+ },
2037
+ {
2038
+ type: "paneldynamic",
2039
+ name: "ixo:attribute",
2040
+ title: "Attributes",
2041
+ templateElements: [
2042
+ {
2043
+ type: "text",
2044
+ name: "schema:ID_2",
2045
+ title: "Attribute ID"
2046
+ },
2047
+ {
2048
+ type: "text",
2049
+ name: "schema:name_2",
2050
+ title: "Name"
2051
+ },
2052
+ {
2053
+ type: "text",
2054
+ name: "schema:description_2",
2055
+ title: "Description"
2056
+ }
2057
+ ]
2058
+ }
2059
+ ]
2060
+ },
2061
+ {
2062
+ name: "project",
2063
+ visibleIf: "{ixo:advancedDomainSettings} = true",
2064
+ title: "Project Information",
2065
+ description: "Provide details about the related project(s), including objectives, sponsors, and deliverables.",
2066
+ elements: [
2067
+ {
2068
+ type: "paneldynamic",
2069
+ name: "pannel_proj:project",
2070
+ title: "Projects",
2071
+ templateElements: [
2072
+ {
2073
+ type: "text",
2074
+ name: "proj:project.name",
2075
+ title: "Project Title"
2076
+ },
2077
+ {
2078
+ type: "comment",
2079
+ name: "proj:project.description",
2080
+ title: "Project Mission",
2081
+ description: "High-level purpose or mission statement of the project."
2082
+ },
2083
+ {
2084
+ type: "paneldynamic",
2085
+ name: "proj:project.hadObjective",
2086
+ title: "Project Objectives",
2087
+ templateElements: [
2088
+ {
2089
+ type: "comment",
2090
+ name: "proj:hadObjective",
2091
+ title: "Project Objective"
2092
+ }
2093
+ ]
2094
+ },
2095
+ {
2096
+ type: "text",
2097
+ name: "proj:plannedStart",
2098
+ title: "Planned Start Date",
2099
+ inputType: "datetime-local"
2100
+ },
2101
+ {
2102
+ type: "text",
2103
+ name: "proj:plannedEnd",
2104
+ title: "Planned End Date",
2105
+ inputType: "datetime-local"
2106
+ },
2107
+ {
2108
+ type: "paneldynamic",
2109
+ name: "proj:wasFundedThrough",
2110
+ title: "Project Funding",
2111
+ templateElements: [
2112
+ {
2113
+ type: "text",
2114
+ name: "proj:moneyAmount",
2115
+ title: "Funding Amount"
2116
+ },
2117
+ {
2118
+ type: "text",
2119
+ name: "proj:moneyCurrency",
2120
+ title: "Funding Currency"
2121
+ },
2122
+ {
2123
+ type: "text",
2124
+ name: "prov.agent.name",
2125
+ title: "Funder Name"
2126
+ },
2127
+ {
2128
+ type: "text",
2129
+ name: "prov:agent.id",
2130
+ title: "Funder URL",
2131
+ inputType: "url"
2132
+ }
2133
+ ]
2134
+ }
2135
+ ]
2136
+ }
2137
+ ]
2138
+ },
2139
+ {
2140
+ name: "researchProfile",
2141
+ title: "Research Profile",
2142
+ description: "Provide information about the research profile associated with the domain.",
2143
+ elements: [
2144
+ {
2145
+ type: "paneldynamic",
2146
+ name: "ixo:ResearchProfile",
2147
+ title: "Seed Queries",
2148
+ templateElements: [
2149
+ {
2150
+ type: "comment",
2151
+ name: "ixo:seedQueries",
2152
+ title: "Seed Query",
2153
+ description: "Seed keywords or queries that define the research scope."
2154
+ }
2155
+ ]
2156
+ },
2157
+ {
2158
+ type: "paneldynamic",
2159
+ name: "schema:creativeWork",
2160
+ title: "Citations",
2161
+ templateElements: [
2162
+ {
2163
+ type: "text",
2164
+ name: "schema:creativeWork.name",
2165
+ title: "Citation Title"
2166
+ },
2167
+ {
2168
+ type: "text",
2169
+ name: "schema:creativeWork.url",
2170
+ title: "Citation URL"
2171
+ },
2172
+ {
2173
+ type: "text",
2174
+ name: "schema:creativeWork.publisher",
2175
+ title: "Publisher"
2176
+ },
2177
+ {
2178
+ type: "text",
2179
+ name: "schema:creativeWork.datePublished",
2180
+ title: "Date Published",
2181
+ inputType: "datetime-local"
2182
+ }
2183
+ ]
2184
+ }
2185
+ ]
2186
+ }
2187
+ ],
2188
+ showPageTitles: false,
2189
+ showQuestionNumbers: "on",
2190
+ showProgressBar: true,
2191
+ progressBarLocation: "top"
2192
+ };
2193
+
2194
+ // src/core/lib/actionRegistry/actions/domainSign.ts
2195
+ registerAction({
2196
+ type: "qi/domain.sign",
2197
+ can: "domain/sign",
2198
+ sideEffect: true,
2199
+ defaultRequiresConfirmation: true,
2200
+ requiredCapability: "flow/block/execute",
2201
+ outputSchema: [
2202
+ { path: "entityDid", displayName: "Entity DID", type: "string", description: "The DID of the newly created domain entity" },
2203
+ { path: "transactionHash", displayName: "Transaction Hash", type: "string", description: "The on-chain transaction hash for domain creation" }
2204
+ ],
2205
+ run: async (inputs, ctx) => {
2206
+ const handlers = ctx.handlers;
2207
+ if (!handlers) {
2208
+ throw new Error("Handlers not available");
2209
+ }
2210
+ if (!handlers.requestPin) throw new Error("requestPin handler not available");
2211
+ if (!handlers.signCredential) throw new Error("signCredential handler not implemented");
2212
+ if (!handlers.publicFileUpload) throw new Error("publicFileUpload handler not available");
2213
+ if (!handlers.createDomain) throw new Error("createDomain handler not implemented");
2214
+ let domainCardData;
2215
+ if (typeof inputs.domainCardData === "string") {
2216
+ try {
2217
+ domainCardData = JSON.parse(inputs.domainCardData);
2218
+ } catch {
2219
+ throw new Error("domainCardData must be valid JSON");
1681
2220
  }
2221
+ } else if (inputs.domainCardData && typeof inputs.domainCardData === "object") {
2222
+ domainCardData = inputs.domainCardData;
2223
+ } else {
2224
+ throw new Error("domainCardData is required");
1682
2225
  }
2226
+ if (!domainCardData?.credentialSubject?.name) {
2227
+ throw new Error("domainCardData is missing or invalid (credentialSubject.name required)");
2228
+ }
2229
+ const extractEntityType = (type) => type.replace(/^schema:/i, "").toLowerCase();
2230
+ const entityType = String(inputs.entityType || "").trim() || (domainCardData.credentialSubject?.type?.[0] ? extractEntityType(domainCardData.credentialSubject.type[0]) : "dao");
1683
2231
  const issuerDid = handlers.getEntityDid?.() || handlers.getCurrentUser?.()?.address;
1684
2232
  if (!issuerDid) throw new Error("Unable to determine issuer DID");
1685
- const entityDid = "did:ixo:entity:pending";
1686
- const credentialSubject = transformSurveyToCredentialSubject(surveyData, entityDid);
2233
+ const entityDidPlaceholder = "did:ixo:entity:pending";
2234
+ const validFrom = domainCardData.validFrom || (/* @__PURE__ */ new Date()).toISOString();
2235
+ const validUntil = domainCardData.validUntil || (() => {
2236
+ const d = /* @__PURE__ */ new Date();
2237
+ d.setFullYear(d.getFullYear() + 100);
2238
+ return d.toISOString();
2239
+ })();
2240
+ const credentialSubject = {
2241
+ ...domainCardData.credentialSubject,
2242
+ id: entityDidPlaceholder
2243
+ };
1687
2244
  const unsignedCredential = buildVerifiableCredential({
1688
- entityDid,
2245
+ entityDid: entityDidPlaceholder,
1689
2246
  issuerDid,
1690
2247
  credentialSubject,
1691
- validFrom: surveyData["schema:validFrom"] || (/* @__PURE__ */ new Date()).toISOString(),
1692
- validUntil: surveyData["schema:validUntil"]
2248
+ validFrom,
2249
+ validUntil
1693
2250
  });
1694
2251
  const pin = await handlers.requestPin({
1695
2252
  title: "Sign Domain Card",
@@ -1710,24 +2267,160 @@ registerAction({
1710
2267
  });
1711
2268
  const uploadResult = await handlers.publicFileUpload(credentialFile);
1712
2269
  const domainCardLinkedResource = buildDomainCardLinkedResource({
1713
- entityDid,
2270
+ entityDid: entityDidPlaceholder,
1714
2271
  cid: uploadResult.cid,
1715
2272
  serviceEndpoint: uploadResult.url,
1716
- description: `Domain Card for ${surveyData["schema:name"] || "Domain"}`
2273
+ description: `Domain Card for ${domainCardData.credentialSubject?.name || "Domain"}`
1717
2274
  });
1718
- const finalEntityType = surveyData["type_2"] || surveyData["daoType"] || configEntityType;
2275
+ let linkedEntitiesData = [];
2276
+ if (inputs.linkedEntities) {
2277
+ if (typeof inputs.linkedEntities === "string") {
2278
+ try {
2279
+ linkedEntitiesData = JSON.parse(inputs.linkedEntities);
2280
+ } catch {
2281
+ }
2282
+ } else if (Array.isArray(inputs.linkedEntities)) {
2283
+ linkedEntitiesData = inputs.linkedEntities;
2284
+ }
2285
+ }
2286
+ const governanceGroupLinkedEntities = buildGovernanceGroupLinkedEntities(parseLinkedEntities(JSON.stringify(linkedEntitiesData)));
2287
+ const endDate = domainCardData.endDate || validUntil;
1719
2288
  const { entityDid: newEntityDid, transactionHash } = await handlers.createDomain({
1720
- entityType: finalEntityType,
2289
+ entityType,
1721
2290
  linkedResource: [domainCardLinkedResource],
1722
- startDate: surveyData["schema:validFrom"],
1723
- endDate: surveyData["schema:validUntil"]
2291
+ linkedEntity: governanceGroupLinkedEntities.length > 0 ? governanceGroupLinkedEntities : void 0,
2292
+ startDate: validFrom,
2293
+ endDate
1724
2294
  });
1725
2295
  return {
1726
2296
  output: {
1727
2297
  entityDid: newEntityDid,
1728
- transactionHash,
1729
- credentialId: uploadResult.cid,
1730
- entityType: finalEntityType
2298
+ transactionHash
2299
+ }
2300
+ };
2301
+ }
2302
+ });
2303
+
2304
+ // src/core/lib/actionRegistry/actions/domainCardBuild.ts
2305
+ registerAction({
2306
+ type: "qi/domain.card-build",
2307
+ can: "domain/card-build",
2308
+ sideEffect: false,
2309
+ defaultRequiresConfirmation: false,
2310
+ outputSchema: [
2311
+ {
2312
+ path: "domainCardData",
2313
+ displayName: "Domain Card Data",
2314
+ type: "object",
2315
+ description: "Unsigned domain card envelope { credentialSubject, validFrom, validUntil } ready for preview and signing"
2316
+ },
2317
+ { path: "unsignedCredential", displayName: "Unsigned Credential", type: "object", description: "The full unsigned W3C Verifiable Credential" },
2318
+ { path: "credentialSubject", displayName: "Credential Subject", type: "object", description: "The ixo:DomainCard credentialSubject extracted from the survey" },
2319
+ { path: "surveyData", displayName: "Survey Answers", type: "object", description: "Raw survey answers used to build the card" },
2320
+ { path: "entityType", displayName: "Entity Type", type: "string", description: "Resolved entity type (from survey or configured default)" },
2321
+ { path: "issuerDid", displayName: "Issuer DID", type: "string", description: "DID of the user or entity that built the card" }
2322
+ ],
2323
+ run: async (inputs, ctx) => {
2324
+ const handlers = ctx.handlers;
2325
+ if (!handlers) throw new Error("Handlers not available");
2326
+ const configEntityType = String(inputs.entityType || "dao").trim();
2327
+ let surveyData = {};
2328
+ if (inputs.surveyData) {
2329
+ if (typeof inputs.surveyData === "string") {
2330
+ try {
2331
+ surveyData = JSON.parse(inputs.surveyData);
2332
+ } catch {
2333
+ throw new Error("surveyData must be valid JSON");
2334
+ }
2335
+ } else if (typeof inputs.surveyData === "object" && !Array.isArray(inputs.surveyData)) {
2336
+ surveyData = inputs.surveyData;
2337
+ }
2338
+ }
2339
+ if (!surveyData || Object.keys(surveyData).length === 0) {
2340
+ throw new Error("surveyData is required to build a domain card");
2341
+ }
2342
+ const issuerDid = handlers.getEntityDid?.() || handlers.getCurrentUser?.()?.address;
2343
+ if (!issuerDid) throw new Error("Unable to determine issuer DID");
2344
+ const entityDidPlaceholder = "did:ixo:entity:pending";
2345
+ const credentialSubject = transformSurveyToCredentialSubject(surveyData, entityDidPlaceholder);
2346
+ const validFrom = surveyData["schema:validFrom"] || (/* @__PURE__ */ new Date()).toISOString();
2347
+ const validUntil = surveyData["schema:validUntil"] || (() => {
2348
+ const d = new Date(validFrom);
2349
+ d.setFullYear(d.getFullYear() + 5);
2350
+ return d.toISOString();
2351
+ })();
2352
+ const unsignedCredential = buildVerifiableCredential({
2353
+ entityDid: entityDidPlaceholder,
2354
+ issuerDid,
2355
+ credentialSubject,
2356
+ validFrom,
2357
+ validUntil
2358
+ });
2359
+ const resolvedEntityType = surveyData["type_2"] || surveyData["daoType"] || configEntityType;
2360
+ const domainCardData = {
2361
+ credentialSubject,
2362
+ validFrom,
2363
+ validUntil
2364
+ };
2365
+ return {
2366
+ output: {
2367
+ domainCardData,
2368
+ unsignedCredential,
2369
+ credentialSubject,
2370
+ surveyData,
2371
+ entityType: resolvedEntityType,
2372
+ issuerDid
2373
+ }
2374
+ };
2375
+ }
2376
+ });
2377
+
2378
+ // src/core/lib/actionRegistry/actions/domainCardPreview.ts
2379
+ registerAction({
2380
+ type: "qi/domain.card-preview",
2381
+ can: "domain/card-preview",
2382
+ sideEffect: false,
2383
+ defaultRequiresConfirmation: false,
2384
+ outputSchema: [
2385
+ {
2386
+ path: "domainCardData",
2387
+ displayName: "Domain Card Data",
2388
+ type: "object",
2389
+ description: "Approved domain card envelope { credentialSubject, validFrom, validUntil } ready to sign"
2390
+ },
2391
+ { path: "domainPreviewData", displayName: "Preview Data", type: "object", description: "Oracle-enriched human-facing preview of the domain card" },
2392
+ { path: "status", displayName: "Status", type: "string", description: "pending | loading | ready | approved | error" },
2393
+ { path: "approvedAt", displayName: "Approved At", type: "number", description: "Timestamp when the user approved the preview" }
2394
+ ],
2395
+ run: async (inputs) => {
2396
+ let domainCardData = inputs.domainCardData;
2397
+ if (typeof domainCardData === "string") {
2398
+ try {
2399
+ domainCardData = JSON.parse(domainCardData);
2400
+ } catch {
2401
+ throw new Error("domainCardData must be valid JSON");
2402
+ }
2403
+ }
2404
+ if (!domainCardData || typeof domainCardData !== "object") {
2405
+ throw new Error("domainCardData is required to preview a domain card");
2406
+ }
2407
+ if (!domainCardData.credentialSubject?.name) {
2408
+ throw new Error("domainCardData.credentialSubject.name is required");
2409
+ }
2410
+ let domainPreviewData = inputs.domainPreviewData;
2411
+ if (typeof domainPreviewData === "string") {
2412
+ try {
2413
+ domainPreviewData = JSON.parse(domainPreviewData);
2414
+ } catch {
2415
+ domainPreviewData = void 0;
2416
+ }
2417
+ }
2418
+ return {
2419
+ output: {
2420
+ domainCardData,
2421
+ domainPreviewData,
2422
+ status: "approved",
2423
+ approvedAt: Date.now()
1731
2424
  }
1732
2425
  };
1733
2426
  }
@@ -3546,7 +4239,8 @@ var ICON_DEFAULTS = {
3546
4239
  "matrix/dm": "message-circle",
3547
4240
  "proposal/create": "scroll",
3548
4241
  "proposal/vote": "vote",
3549
- "domain/create": "globe",
4242
+ "domain/card-build": "file-text",
4243
+ "domain/card-preview": "id",
3550
4244
  "domain/sign": "feather",
3551
4245
  "credential/store": "shield",
3552
4246
  "payment/execute": "credit-card",
@@ -4385,12 +5079,7 @@ export {
4385
5079
  buildServicesFromHandlers,
4386
5080
  getDiffResolver,
4387
5081
  hasDiffResolver,
4388
- buildVerifiableCredential,
4389
- buildDomainCardLinkedResource,
4390
- parseLinkedEntities,
4391
- buildGovernanceGroupLinkedEntities,
4392
- transformSurveyToCredentialSubject,
4393
- extractSurveyAnswersTemplate,
5082
+ tempDomainCreatorSurvey,
4394
5083
  getHomeserver,
4395
5084
  didToMatrixUserId,
4396
5085
  findOrCreateDMRoom,
@@ -4433,4 +5122,4 @@ export {
4433
5122
  readFlow,
4434
5123
  setupFlowFromBaseUcan
4435
5124
  };
4436
- //# sourceMappingURL=chunk-JHQO6FAQ.mjs.map
5125
+ //# sourceMappingURL=chunk-4ETFMWQR.mjs.map