Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
66b820f
fix(eslint): change no-unused-vars rule to error level
Sotatek-DucPhung Oct 17, 2025
96ffe4c
fix(tests): correct usage of optional chaining in connectionService t…
Sotatek-DucPhung Oct 17, 2025
c4d120b
fix(core): ensure contact exists before accessing properties in conne…
Sotatek-DucPhung Oct 17, 2025
a674fd5
fix(core): improve error handling and structure in connection details…
Sotatek-DucPhung Oct 17, 2025
29c0392
fix(core): add agent initialization check in identifier creation
Sotatek-DucPhung Oct 17, 2025
d0d14bf
refactor(core): simplify cloudIdentifiers type definition in syncKeri…
Sotatek-DucPhung Oct 17, 2025
e5871cc
fix(core): enforce presence of e.acdc in CREDENTIAL_REVOKED messages …
Sotatek-DucPhung Oct 17, 2025
8a21efe
fix(core): add initialization check for signify client manager in Ipe…
Sotatek-DucPhung Oct 17, 2025
78187a4
fix(core): improve error handling by throwing an error when contact i…
Sotatek-DucPhung Oct 17, 2025
192c29f
fix(core): standardize error messages for signify client manager init…
Sotatek-DucPhung Oct 17, 2025
67420e7
fix(core): update type handling for record tags in IonicStorage to im…
Sotatek-DucPhung Oct 17, 2025
0e42e01
fix(tests): remove optional chaining for historyItems in connectionSe…
Sotatek-DucPhung Oct 29, 2025
e045043
fix(core): update type definition for item tags in migration utilitie…
Sotatek-DucPhung Oct 31, 2025
c94d9f6
feat(core): introduce ACDC type and integrate it into credential hand…
Sotatek-DucPhung Oct 31, 2025
61a8b35
fix(core): update ExnMessage types to use unknown for exn structure a…
Sotatek-DucPhung Oct 31, 2025
d91008e
fix(core): enhance type safety and validation for ExnMessage structur…
Sotatek-DucPhung Oct 31, 2025
8252425
fix(core): improve type exports and enhance group data handling in Mu…
Sotatek-DucPhung Oct 31, 2025
2462d86
fix(core): enhance type safety for queued group creation and improve …
Sotatek-DucPhung Oct 31, 2025
2979559
fix(core): improve type safety for queued group handling in MultiSigS…
Sotatek-DucPhung Oct 31, 2025
0c23980
fix(core): enhance type safety for identifier metadata handling in SQ…
Sotatek-DucPhung Nov 3, 2025
6b4d850
fix(core): refine type definitions for ACDC handling in IpexCommunica…
Sotatek-DucPhung Nov 3, 2025
9202fbf
fix(core): refine type definition for offerExnToJoin
Sotatek-DucPhung Nov 3, 2025
5ef8843
fix(core): enhance type safety for queued group creation
Sotatek-DucPhung Nov 3, 2025
b13d94c
fix(core): improve type safety for ACDC
Sotatek-DucPhung Nov 3, 2025
b2d50ab
chore(core): revert logic
Sotatek-DucPhung Nov 3, 2025
cd1f9f3
fix(core): improve type safety for multisig creation
Sotatek-DucPhung Nov 3, 2025
12e33c2
fix(core): rename type guard for multisig exchange messages
Sotatek-DucPhung Nov 3, 2025
2e8005e
fix(core): add type guard for group inception data in multisig service
Sotatek-DucPhung Nov 5, 2025
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: 4 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@
"@typescript-eslint/no-duplicate-enum-values": "error",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
"@typescript-eslint/no-unused-vars": [
"error",
{ "argsIgnorePattern": "^_" }
],
"react/no-unescaped-entities": 0,
"react/react-in-jsx-scope": "off",
"no-console": "error",
Expand Down
4 changes: 3 additions & 1 deletion src/core/__fixtures__/agent/ipexCommunicationFixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,9 @@ const multisigExnGrant = {
d: "EE8_Xc0ZUh_sUJLtmBpVSEr-RFS2mRUIpFyL-pmvtPvx",
},
},
pathed: {},
pathed: {
exn: "d",
},
};

const credentialRecord = {
Expand Down
4 changes: 3 additions & 1 deletion src/core/__fixtures__/agent/keriaNotificationFixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,9 @@ const multisigExnGrant = {
d: "EE8_Xc0ZUh_sUJLtmBpVSEr-RFS2mRUIpFyL-pmvtPvx",
},
},
pathed: {},
pathed: {
exn: "d",
},
};

const notificationMultisigRpyProp = {
Expand Down
6 changes: 3 additions & 3 deletions src/core/__fixtures__/agent/multiSigFixtures.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CreateIdentifierBody, Tier } from "signify-ts";
import { CreateIdentifierBody, HabState, Tier } from "signify-ts";
import { ConnectionStatus, CreationStatus } from "../../agent/agent.types";
import {
IdentifierMetadataRecord,
Expand Down Expand Up @@ -862,7 +862,7 @@ const linkedContacts = [

const queuedIdentifier: QueuedGroupCreation & { initiator: true } = {
name: "1.2.0.2:0:Identifier 2",
data: inceptionDataFix,
data: inceptionDataFix as CreateIdentifierBody & { group: HabState },
initiator: true,
groupConnections: linkedContacts,
threshold: {
Expand All @@ -873,7 +873,7 @@ const queuedIdentifier: QueuedGroupCreation & { initiator: true } = {

const queuedJoin: QueuedGroupCreation & { initiator: false } = {
name: "0:testUser",
data: inceptionDataFix,
data: inceptionDataFix as CreateIdentifierBody & { group: HabState },
initiator: false,
notificationId: "notification-id",
notificationSaid: "notification-said",
Expand Down
24 changes: 15 additions & 9 deletions src/core/agent/agent.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,12 @@ interface ExnMessageA {
};
d?: string;
r?: string;
exn?: {
r: string;
p: string;
};
exn?: unknown;
}

// Define types for the 'e' property in ExnMessage
interface ExnMessageE {
acdc: {
acdc?: {
d: string;
i: string;
s: string;
Expand All @@ -152,10 +149,7 @@ interface ExnMessageE {
icp: {
i: string;
};
exn: {
r: string;
p: string;
};
exn: unknown;
[key: string]: unknown;
}

Expand All @@ -181,6 +175,13 @@ type ExnMessage = {
};
};

// Type guard to check if ExnMessageE has acdc
function exnHasAcdc(
e: ExnMessageE
): e is ExnMessageE & { acdc: NonNullable<ExnMessageE["acdc"]> } {
return e.acdc !== undefined && e.acdc !== null;
}

type ConnectionNoteProps = Pick<ConnectionNoteDetails, "title" | "message">;

interface ConnectionDetailsExtras {
Expand Down Expand Up @@ -264,13 +265,18 @@ export const OOBI_AGENT_ONLY_RE =
export const DOOBI_RE = /^\/oobi\/(?<said>[^/]+)$/i;
export const WOOBI_RE = /^\/\.well-known\/keri\/oobi\/(?<cid>[^/]+)$/;

// Common error messages
export const SIGNIFY_CLIENT_MANAGER_NOT_INITIALIZED =
"Signify client manager not initialized";

export {
ConnectionStatus,
MiscRecordId,
OobiType,
CreationStatus,
isRegularConnectionDetails,
isMultisigConnectionDetails,
exnHasAcdc,
};

export type {
Expand Down
4 changes: 2 additions & 2 deletions src/core/agent/services/connectionService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1911,7 +1911,7 @@ describe("Connection service of agent", () => {
});
expect(result.historyItems).toHaveLength(2);
expect(
result.historyItems?.some(
result.historyItems.some(
(item) => item.type === ConnectionHistoryType.IPEX_AGREE_COMPLETE
)
).toBe(true);
Expand Down Expand Up @@ -1991,7 +1991,7 @@ describe("Connection service of agent", () => {
});
expect(result.historyItems).toHaveLength(1);
expect(
result.historyItems?.some(
result.historyItems.some(
(item) => item.type === ConnectionHistoryType.IPEX_AGREE_COMPLETE
)
).toBe(false);
Expand Down
37 changes: 22 additions & 15 deletions src/core/agent/services/connectionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,18 +258,22 @@ class ConnectionService extends AgentService {
}
const contact = contactRecordMap.get(connectionPair.contactId);

if (contact?.alias && contact?.oobi) {
connections.push({
id: connectionPair.contactId,
alias: contact.alias,
createdAt: connectionPair.createdAt,
oobi: contact.oobi,
groupId: contact.groupId,
creationStatus: connectionPair.creationStatus,
pendingDeletion: connectionPair.pendingDeletion,
identifier: connectionPair.identifier, // Include identifier from connection pair
});
if (!contact) {
throw new Error(
`Contact missing from map for contactId: ${connectionPair.contactId}`
);
}

connections.push({
id: connectionPair.contactId,
alias: contact.alias,
createdAt: connectionPair.createdAt,
oobi: contact.oobi,
groupId: contact.groupId,
creationStatus: connectionPair.creationStatus,
pendingDeletion: connectionPair.pendingDeletion,
identifier: connectionPair.identifier, // Include identifier from connection pair
});
}

return connections.map((connection) =>
Expand Down Expand Up @@ -312,17 +316,20 @@ class ConnectionService extends AgentService {
status = ConnectionStatus.FAILED;
}

return {
const baseDetails = {
id: record.id,
label: record.alias,
createdAtUTC: record.createdAt.toISOString(),
status,
oobi: record.oobi,
contactId: record.id,
...(record.groupId
? { groupId: record.groupId }
: { identifier: record.identifier || "" }),
};

if (record.groupId !== undefined) {
return { ...baseDetails, groupId: record.groupId };
}

return { ...baseDetails, identifier: record.identifier || "" };
}

async getConnectionById(
Expand Down
17 changes: 16 additions & 1 deletion src/core/agent/services/credentialService.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@ enum CredentialStatus {

type CredentialShortDetails = Omit<CredentialMetadataRecordProps, "createdAt">;

interface ACDC {
v: string;
d: string;
i: string;
ri: string;
s: string;
a: {
d: string;
i: string;
dt: string;
[key: string]: unknown;
};
[key: string]: unknown;
}

interface ACDCDetails
extends Omit<CredentialShortDetails, "credentialType" | "issuanceDate"> {
i: string;
Expand Down Expand Up @@ -45,4 +60,4 @@ interface KeriaCredential {
}

export { CredentialStatus };
export type { CredentialShortDetails, ACDCDetails, KeriaCredential };
export type { CredentialShortDetails, ACDCDetails, KeriaCredential, ACDC };
40 changes: 27 additions & 13 deletions src/core/agent/services/identifier.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CreateIdentifierBody } from "signify-ts";
import { CreateIdentifierBody, HabState } from "signify-ts";
import {
MultisigConnectionDetails,
CreationStatus,
Expand Down Expand Up @@ -61,29 +61,46 @@ enum IdentifierType {
Group = "group",
}

type QueuedIdentifierCreation = {
name: string;
data: CreateIdentifierBody;
};

interface MultisigThresholds {
signingThreshold: number;
rotationThreshold: number;
}

type QueuedGroupProps =
type QueuedGroupCreation =
| {
initiator: true;
name: string;
data: CreateIdentifierBody & { group: HabState };
groupConnections: MultisigConnectionDetails[];
threshold: number | MultisigThresholds;
}
| {
initiator: false;
name: string;
data: CreateIdentifierBody & { group: HabState };
notificationId: string;
notificationSaid: string;
};

type QueuedGroupCreation = QueuedIdentifierCreation & QueuedGroupProps;
// Type guard to check if CreateIdentifierBody has group data
function isGroupInceptionData(
data: CreateIdentifierBody
): data is CreateIdentifierBody & { group: HabState } {
return data.group !== undefined;
}

// Helper type used in multiSigService for generating inception data
type QueuedGroupProps =
| {
initiator: true;
groupConnections: MultisigConnectionDetails[];
threshold: number | MultisigThresholds;
}
| {
initiator: false;
notificationId: string;
notificationSaid: string;
};

interface GroupParticipants {
ourIdentifier: IdentifierMetadataRecord;
Expand All @@ -110,19 +127,16 @@ interface RemoteSignRequest {
payload: JSONObject;
}

export { IdentifierType, isGroupInceptionData };

export type {
IdentifierShortDetails,
IdentifierDetails,
MultiSigIcpRequestDetails,
CreateIdentifierInputs,
CreateIdentifierResult,
MultisigThresholds,
};

export { IdentifierType };
export type {
GroupMetadata,
QueuedIdentifierCreation,
QueuedGroupProps,
QueuedGroupCreation,
GroupParticipants,
Expand Down
31 changes: 12 additions & 19 deletions src/core/agent/services/identifierService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ class IdentifierService extends AgentService {
metadata: Omit<IdentifierMetadataRecordProps, "id" | "createdAt">,
backgroundTask = false
): Promise<CreateIdentifierResult> {
if (!this.props.signifyClient.agent) {
throw new Error("Agent not initialized");
}

const { toad, witnesses } = await this.getAvailableWitnesses();

if (!UI_THEMES.includes(metadata.theme)) {
Expand Down Expand Up @@ -303,9 +307,6 @@ class IdentifierService extends AgentService {
.identifiers()
.get(identifier)) as HabState;

if (!this.props.signifyClient.agent) {
throw new Error("Agent not initialized");
}
const addRoleOperation = await this.props.signifyClient
.identifiers()
.addEndRole(identifier, "agent", this.props.signifyClient.agent.pre);
Expand Down Expand Up @@ -658,16 +659,7 @@ class IdentifierService extends AgentService {
}

async syncKeriaIdentifiers(): Promise<void> {
const cloudIdentifiers: Array<{
prefix: string;
name: string;
group?: {
mhab: {
name: string;
prefix: string;
};
};
}> = [];
const cloudIdentifiers: HabState[] = [];
let returned = -1;
let iteration = 0;

Expand All @@ -683,8 +675,10 @@ class IdentifierService extends AgentService {

const localIdentifiers = await this.identifierStorage.getAllIdentifiers();

const unSyncedDataWithGroup = [];
const unSyncedDataWithoutGroup = [];
const unSyncedDataWithGroup: (HabState & {
group: NonNullable<HabState["group"]>;
})[] = [];
const unSyncedDataWithoutGroup: HabState[] = [];
for (const identifier of cloudIdentifiers) {
if (localIdentifiers.find((item) => item.id === identifier.prefix)) {
continue;
Expand All @@ -693,7 +687,9 @@ class IdentifierService extends AgentService {
if (identifier.group === undefined) {
unSyncedDataWithoutGroup.push(identifier);
} else {
unSyncedDataWithGroup.push(identifier);
unSyncedDataWithGroup.push(
identifier as HabState & { group: NonNullable<HabState["group"]> }
);
}
}

Expand Down Expand Up @@ -762,9 +758,6 @@ class IdentifierService extends AgentService {
.identifiers()
.get(identifier.prefix)) as HabState;

if (!identifier.group) {
throw new Error("Group identifier missing group data");
}
const nameToParse = identifier.name.startsWith(
IdentifierService.DELETED_IDENTIFIER_THEME
)
Expand Down
Loading