|
|
@ -38,7 +38,14 @@ import { |
|
|
|
getPasskeyExpirationSeconds, |
|
|
|
} from "../libs/util"; |
|
|
|
import { createEndorserJwtForKey } from "../libs/crypto/vc"; |
|
|
|
import { KeyMeta } from "../interfaces/common"; |
|
|
|
import { |
|
|
|
GiveActionClaim, |
|
|
|
JoinActionClaim, |
|
|
|
OfferClaim, |
|
|
|
PlanActionClaim, |
|
|
|
RegisterActionClaim, |
|
|
|
TenureClaim, |
|
|
|
} from "../interfaces/claims"; |
|
|
|
|
|
|
|
import { |
|
|
|
GenericCredWrapper, |
|
|
@ -46,15 +53,13 @@ import { |
|
|
|
AxiosErrorResponse, |
|
|
|
UserInfo, |
|
|
|
CreateAndSubmitClaimResult, |
|
|
|
PlanSummaryRecord, |
|
|
|
GiveVerifiableCredential, |
|
|
|
OfferVerifiableCredential, |
|
|
|
RegisterVerifiableCredential, |
|
|
|
ClaimObject, |
|
|
|
VerifiableCredentialClaim, |
|
|
|
Agent, |
|
|
|
QuantitativeValue, |
|
|
|
KeyMetaWithPrivate, |
|
|
|
KeyMetaMaybeWithPrivate, |
|
|
|
} from "../interfaces/common"; |
|
|
|
import { PlanSummaryRecord } from "../interfaces/records"; |
|
|
|
import { logger } from "../utils/logger"; |
|
|
|
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory"; |
|
|
|
|
|
|
@ -650,7 +655,7 @@ export async function getNewOffersToUserProjects( |
|
|
|
* @param lastClaimId supplied when editing a previous claim |
|
|
|
*/ |
|
|
|
export function hydrateGive( |
|
|
|
vcClaimOrig?: GiveVerifiableCredential, |
|
|
|
vcClaimOrig?: GiveActionClaim, |
|
|
|
fromDid?: string, |
|
|
|
toDid?: string, |
|
|
|
description?: string, |
|
|
@ -662,8 +667,8 @@ export function hydrateGive( |
|
|
|
imageUrl?: string, |
|
|
|
providerPlanHandleId?: string, |
|
|
|
lastClaimId?: string, |
|
|
|
): GiveVerifiableCredential { |
|
|
|
const vcClaim: GiveVerifiableCredential = vcClaimOrig |
|
|
|
): GiveActionClaim { |
|
|
|
const vcClaim: GiveActionClaim = vcClaimOrig |
|
|
|
? R.clone(vcClaimOrig) |
|
|
|
: { |
|
|
|
"@context": SCHEMA_ORG_CONTEXT, |
|
|
@ -694,7 +699,7 @@ export function hydrateGive( |
|
|
|
|
|
|
|
// Initialize fulfills array if not present
|
|
|
|
if (!Array.isArray(vcClaim.fulfills)) { |
|
|
|
vcClaim.fulfills = []; |
|
|
|
vcClaim.fulfills = vcClaim.fulfills ? [vcClaim.fulfills] : []; |
|
|
|
} |
|
|
|
|
|
|
|
// Filter and add fulfills elements
|
|
|
@ -797,7 +802,7 @@ export async function createAndSubmitGive( |
|
|
|
export async function editAndSubmitGive( |
|
|
|
axios: Axios, |
|
|
|
apiServer: string, |
|
|
|
fullClaim: GenericCredWrapper<GiveVerifiableCredential>, |
|
|
|
fullClaim: GenericCredWrapper<GiveActionClaim>, |
|
|
|
issuerDid: string, |
|
|
|
fromDid?: string, |
|
|
|
toDid?: string, |
|
|
@ -838,7 +843,7 @@ export async function editAndSubmitGive( |
|
|
|
* @param lastClaimId supplied when editing a previous claim |
|
|
|
*/ |
|
|
|
export function hydrateOffer( |
|
|
|
vcClaimOrig?: OfferVerifiableCredential, |
|
|
|
vcClaimOrig?: OfferClaim, |
|
|
|
fromDid?: string, |
|
|
|
toDid?: string, |
|
|
|
itemDescription?: string, |
|
|
@ -848,8 +853,8 @@ export function hydrateOffer( |
|
|
|
fulfillsProjectHandleId?: string, |
|
|
|
validThrough?: string, |
|
|
|
lastClaimId?: string, |
|
|
|
): OfferVerifiableCredential { |
|
|
|
const vcClaim: OfferVerifiableCredential = vcClaimOrig |
|
|
|
): OfferClaim { |
|
|
|
const vcClaim: OfferClaim = vcClaimOrig |
|
|
|
? R.clone(vcClaimOrig) |
|
|
|
: { |
|
|
|
"@context": SCHEMA_ORG_CONTEXT, |
|
|
@ -857,12 +862,13 @@ export function hydrateOffer( |
|
|
|
}; |
|
|
|
|
|
|
|
if (lastClaimId) { |
|
|
|
// this is an edit
|
|
|
|
vcClaim.lastClaimId = lastClaimId; |
|
|
|
delete vcClaim.identifier; |
|
|
|
} |
|
|
|
|
|
|
|
if (fromDid) { |
|
|
|
vcClaim.agent = { identifier: fromDid }; |
|
|
|
vcClaim.offeredBy = { identifier: fromDid }; |
|
|
|
} |
|
|
|
if (toDid) { |
|
|
|
vcClaim.recipient = { identifier: toDid }; |
|
|
@ -870,12 +876,10 @@ export function hydrateOffer( |
|
|
|
vcClaim.description = conditionDescription || undefined; |
|
|
|
|
|
|
|
if (amount && !isNaN(amount)) { |
|
|
|
const quantitativeValue: QuantitativeValue = { |
|
|
|
"@type": "QuantitativeValue", |
|
|
|
vcClaim.includesObject = { |
|
|
|
amountOfThisGood: amount, |
|
|
|
unitCode: unitCode || "HUR", |
|
|
|
}; |
|
|
|
vcClaim.object = quantitativeValue; |
|
|
|
} |
|
|
|
|
|
|
|
if (itemDescription || fulfillsProjectHandleId) { |
|
|
@ -928,7 +932,7 @@ export async function createAndSubmitOffer( |
|
|
|
undefined, |
|
|
|
); |
|
|
|
return createAndSubmitClaim( |
|
|
|
vcClaim as OfferVerifiableCredential, |
|
|
|
vcClaim as OfferClaim, |
|
|
|
issuerDid, |
|
|
|
apiServer, |
|
|
|
axios, |
|
|
@ -938,7 +942,7 @@ export async function createAndSubmitOffer( |
|
|
|
export async function editAndSubmitOffer( |
|
|
|
axios: Axios, |
|
|
|
apiServer: string, |
|
|
|
fullClaim: GenericCredWrapper<OfferVerifiableCredential>, |
|
|
|
fullClaim: GenericCredWrapper<OfferClaim>, |
|
|
|
issuerDid: string, |
|
|
|
itemDescription: string, |
|
|
|
amount?: number, |
|
|
@ -961,7 +965,7 @@ export async function editAndSubmitOffer( |
|
|
|
fullClaim.id, |
|
|
|
); |
|
|
|
return createAndSubmitClaim( |
|
|
|
vcClaim as OfferVerifiableCredential, |
|
|
|
vcClaim as OfferClaim, |
|
|
|
issuerDid, |
|
|
|
apiServer, |
|
|
|
axios, |
|
|
@ -1036,7 +1040,7 @@ export async function createAndSubmitClaim( |
|
|
|
} |
|
|
|
|
|
|
|
export async function generateEndorserJwtUrlForAccount( |
|
|
|
account: KeyMeta, |
|
|
|
account: KeyMetaMaybeWithPrivate, |
|
|
|
isRegistered: boolean, |
|
|
|
givenName: string, |
|
|
|
profileImageUrl: string, |
|
|
@ -1060,7 +1064,7 @@ export async function generateEndorserJwtUrlForAccount( |
|
|
|
} |
|
|
|
|
|
|
|
// Add the next key -- not recommended for the QR code for such a high resolution
|
|
|
|
if (isContact) { |
|
|
|
if (isContact && account.derivationPath && account.mnemonic) { |
|
|
|
const newDerivPath = nextDerivationPath(account.derivationPath); |
|
|
|
const nextPublicHex = deriveAddress(account.mnemonic, newDerivPath)[2]; |
|
|
|
const nextPublicEncKey = Buffer.from(nextPublicHex, "hex"); |
|
|
@ -1082,7 +1086,11 @@ export async function createEndorserJwtForDid( |
|
|
|
expiresIn?: number, |
|
|
|
) { |
|
|
|
const account = await retrieveFullyDecryptedAccount(issuerDid); |
|
|
|
return createEndorserJwtForKey(account as KeyMeta, payload, expiresIn); |
|
|
|
return createEndorserJwtForKey( |
|
|
|
account as KeyMetaWithPrivate, |
|
|
|
payload, |
|
|
|
expiresIn, |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -1179,102 +1187,118 @@ export const claimSpecialDescription = ( |
|
|
|
identifiers: Array<string>, |
|
|
|
contacts: Array<Contact>, |
|
|
|
) => { |
|
|
|
let claim = record.claim; |
|
|
|
let claim: |
|
|
|
| GenericVerifiableCredential |
|
|
|
| GenericCredWrapper<GenericVerifiableCredential> = record.claim; |
|
|
|
if ("claim" in claim) { |
|
|
|
// it's a nested GenericCredWrapper
|
|
|
|
claim = claim.claim as GenericVerifiableCredential; |
|
|
|
} |
|
|
|
|
|
|
|
const issuer = didInfo(record.issuer, activeDid, identifiers, contacts); |
|
|
|
const claimObj = claim as ClaimObject; |
|
|
|
const type = claimObj["@type"] || "UnknownType"; |
|
|
|
const type = claim["@type"] || "UnknownType"; |
|
|
|
|
|
|
|
if (type === "AgreeAction") { |
|
|
|
return ( |
|
|
|
issuer + |
|
|
|
" agreed with " + |
|
|
|
claimSummary(claimObj.object as GenericVerifiableCredential) |
|
|
|
claimSummary(claim.object as GenericVerifiableCredential) |
|
|
|
); |
|
|
|
} else if (isAccept(claim)) { |
|
|
|
return ( |
|
|
|
issuer + |
|
|
|
" accepted " + |
|
|
|
claimSummary(claimObj.object as GenericVerifiableCredential) |
|
|
|
claimSummary(claim.object as GenericVerifiableCredential) |
|
|
|
); |
|
|
|
} else if (type === "GiveAction") { |
|
|
|
const giveClaim = claim as GiveVerifiableCredential; |
|
|
|
const agent: Agent = giveClaim.agent || { |
|
|
|
identifier: undefined, |
|
|
|
did: undefined, |
|
|
|
}; |
|
|
|
const agentDid = agent.did || agent.identifier; |
|
|
|
const contactInfo = agentDid |
|
|
|
? didInfo(agentDid, activeDid, identifiers, contacts) |
|
|
|
: "someone"; |
|
|
|
const offering = giveClaim.object |
|
|
|
? " " + claimSummary(giveClaim.object) |
|
|
|
const giveClaim = claim as GiveActionClaim; |
|
|
|
// @ts-expect-error because .did may be found in legacy data, before March 2023
|
|
|
|
const legacyGiverDid = giveClaim.agent?.did; |
|
|
|
const giver = giveClaim.agent?.identifier || legacyGiverDid; |
|
|
|
const giverInfo = didInfo(giver, activeDid, identifiers, contacts); |
|
|
|
let gaveAmount = giveClaim.object?.amountOfThisGood |
|
|
|
? displayAmount( |
|
|
|
giveClaim.object.unitCode as string, |
|
|
|
giveClaim.object.amountOfThisGood as number, |
|
|
|
) |
|
|
|
: ""; |
|
|
|
const recipient = giveClaim.participant?.identifier; |
|
|
|
const recipientInfo = recipient |
|
|
|
? " to " + didInfo(recipient, activeDid, identifiers, contacts) |
|
|
|
if (giveClaim.description) { |
|
|
|
if (gaveAmount) { |
|
|
|
gaveAmount = gaveAmount + ", and also: "; |
|
|
|
} |
|
|
|
gaveAmount = gaveAmount + giveClaim.description; |
|
|
|
} |
|
|
|
if (!gaveAmount) { |
|
|
|
gaveAmount = "something not described"; |
|
|
|
} |
|
|
|
// @ts-expect-error because .did may be found in legacy data, before March 2023
|
|
|
|
const legacyRecipDid = giveClaim.recipient?.did; |
|
|
|
const gaveRecipientId = giveClaim.recipient?.identifier || legacyRecipDid; |
|
|
|
const gaveRecipientInfo = gaveRecipientId |
|
|
|
? " to " + didInfo(gaveRecipientId, activeDid, identifiers, contacts) |
|
|
|
: ""; |
|
|
|
return contactInfo + " gave" + offering + recipientInfo; |
|
|
|
return giverInfo + " gave" + gaveRecipientInfo + ": " + gaveAmount; |
|
|
|
} else if (type === "JoinAction") { |
|
|
|
const joinClaim = claim as ClaimObject; |
|
|
|
const agent: Agent = joinClaim.agent || { |
|
|
|
identifier: undefined, |
|
|
|
did: undefined, |
|
|
|
}; |
|
|
|
const agentDid = agent.did || agent.identifier; |
|
|
|
const contactInfo = agentDid |
|
|
|
? didInfo(agentDid, activeDid, identifiers, contacts) |
|
|
|
: "someone"; |
|
|
|
const object = joinClaim.object as GenericVerifiableCredential; |
|
|
|
const objectInfo = object ? " " + claimSummary(object) : ""; |
|
|
|
return contactInfo + " joined" + objectInfo; |
|
|
|
const joinClaim = claim as JoinActionClaim; |
|
|
|
// @ts-expect-error because .did may be found in legacy data, before March 2023
|
|
|
|
const legacyDid = joinClaim.agent?.did; |
|
|
|
const agent = joinClaim.agent?.identifier || legacyDid; |
|
|
|
const contactInfo = didInfo(agent, activeDid, identifiers, contacts); |
|
|
|
|
|
|
|
let eventOrganizer = |
|
|
|
joinClaim.event && |
|
|
|
joinClaim.event.organizer && |
|
|
|
joinClaim.event.organizer.name; |
|
|
|
eventOrganizer = eventOrganizer || ""; |
|
|
|
let eventName = joinClaim.event && joinClaim.event.name; |
|
|
|
eventName = eventName ? " " + eventName : ""; |
|
|
|
let fullEvent = eventOrganizer + eventName; |
|
|
|
fullEvent = fullEvent ? " attended the " + fullEvent : ""; |
|
|
|
|
|
|
|
let eventDate = joinClaim.event && joinClaim.event.startTime; |
|
|
|
eventDate = eventDate ? " at " + eventDate : ""; |
|
|
|
return contactInfo + fullEvent + eventDate; |
|
|
|
} else if (isOffer(claim)) { |
|
|
|
const offerClaim = claim as OfferVerifiableCredential; |
|
|
|
const agent: Agent = offerClaim.agent || { |
|
|
|
identifier: undefined, |
|
|
|
did: undefined, |
|
|
|
}; |
|
|
|
const agentDid = agent.did || agent.identifier; |
|
|
|
const contactInfo = agentDid |
|
|
|
? didInfo(agentDid, activeDid, identifiers, contacts) |
|
|
|
: "someone"; |
|
|
|
const offering = offerClaim.object |
|
|
|
? " " + claimSummary(offerClaim.object) |
|
|
|
: ""; |
|
|
|
const offerRecipientId = offerClaim.participant?.identifier; |
|
|
|
const offerClaim = claim as OfferClaim; |
|
|
|
const offerer = offerClaim.offeredBy?.identifier; |
|
|
|
const contactInfo = didInfo(offerer, activeDid, identifiers, contacts); |
|
|
|
let offering = ""; |
|
|
|
if (offerClaim.includesObject) { |
|
|
|
offering += |
|
|
|
" " + |
|
|
|
displayAmount( |
|
|
|
offerClaim.includesObject.unitCode, |
|
|
|
offerClaim.includesObject.amountOfThisGood, |
|
|
|
); |
|
|
|
} |
|
|
|
if (offerClaim.itemOffered?.description) { |
|
|
|
offering += ", saying: " + offerClaim.itemOffered?.description; |
|
|
|
} |
|
|
|
// @ts-expect-error because .did may be found in legacy data, before March 2023
|
|
|
|
const legacyDid = offerClaim.recipient?.did; |
|
|
|
const offerRecipientId = offerClaim.recipient?.identifier || legacyDid; |
|
|
|
const offerRecipientInfo = offerRecipientId |
|
|
|
? " to " + didInfo(offerRecipientId, activeDid, identifiers, contacts) |
|
|
|
: ""; |
|
|
|
return contactInfo + " offered" + offering + offerRecipientInfo; |
|
|
|
} else if (type === "PlanAction") { |
|
|
|
const planClaim = claim as ClaimObject; |
|
|
|
const agent: Agent = planClaim.agent || { |
|
|
|
identifier: undefined, |
|
|
|
did: undefined, |
|
|
|
}; |
|
|
|
const agentDid = agent.did || agent.identifier; |
|
|
|
const contactInfo = agentDid |
|
|
|
? didInfo(agentDid, activeDid, identifiers, contacts) |
|
|
|
: "someone"; |
|
|
|
const object = planClaim.object as GenericVerifiableCredential; |
|
|
|
const objectInfo = object ? " " + claimSummary(object) : ""; |
|
|
|
return contactInfo + " planned" + objectInfo; |
|
|
|
const planClaim = claim as PlanActionClaim; |
|
|
|
const claimer = planClaim.agent?.identifier || record.issuer; |
|
|
|
const claimerInfo = didInfo(claimer, activeDid, identifiers, contacts); |
|
|
|
return claimerInfo + " announced a project: " + planClaim.name; |
|
|
|
} else if (type === "Tenure") { |
|
|
|
const tenureClaim = claim as ClaimObject; |
|
|
|
const agent: Agent = tenureClaim.agent || { |
|
|
|
identifier: undefined, |
|
|
|
did: undefined, |
|
|
|
}; |
|
|
|
const agentDid = agent.did || agent.identifier; |
|
|
|
const contactInfo = agentDid |
|
|
|
? didInfo(agentDid, activeDid, identifiers, contacts) |
|
|
|
: "someone"; |
|
|
|
const object = tenureClaim.object as GenericVerifiableCredential; |
|
|
|
const objectInfo = object ? " " + claimSummary(object) : ""; |
|
|
|
return contactInfo + " has tenure" + objectInfo; |
|
|
|
const tenureClaim = claim as TenureClaim; |
|
|
|
// @ts-expect-error because .did may be found in legacy data, before March 2023
|
|
|
|
const legacyDid = tenureClaim.party?.did; |
|
|
|
const claimer = tenureClaim.party?.identifier || legacyDid; |
|
|
|
const contactInfo = didInfo(claimer, activeDid, identifiers, contacts); |
|
|
|
const polygon = tenureClaim.spatialUnit?.geo?.polygon || ""; |
|
|
|
return ( |
|
|
|
contactInfo + |
|
|
|
" possesses [" + |
|
|
|
polygon.substring(0, polygon.indexOf(" ")) + |
|
|
|
"...]" |
|
|
|
); |
|
|
|
} else { |
|
|
|
return issuer + " declared " + claimSummary(claim); |
|
|
|
} |
|
|
@ -1331,7 +1355,7 @@ export async function createInviteJwt( |
|
|
|
identifier?: string, |
|
|
|
expiresIn?: number, // in seconds
|
|
|
|
): Promise<string> { |
|
|
|
const vcClaim: RegisterVerifiableCredential = { |
|
|
|
const vcClaim: RegisterActionClaim = { |
|
|
|
"@context": SCHEMA_ORG_CONTEXT, |
|
|
|
"@type": "RegisterAction", |
|
|
|
agent: { identifier: activeDid }, |
|
|
|