|
|
@ -48,29 +48,31 @@ export interface ClaimResult { |
|
|
|
} |
|
|
|
|
|
|
|
export interface GenericVerifiableCredential { |
|
|
|
"@context": string; |
|
|
|
"@context"?: string; |
|
|
|
"@type": string; |
|
|
|
[key: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
|
|
} |
|
|
|
|
|
|
|
export interface GenericCredWrapper extends GenericVerifiableCredential { |
|
|
|
export interface GenericCredWrapper<T extends GenericVerifiableCredential> { |
|
|
|
"@context": string; |
|
|
|
"@type": string; |
|
|
|
handleId: string; |
|
|
|
id: string; |
|
|
|
issuedAt: string; |
|
|
|
issuer: string; |
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
claim: Record<string, any>; |
|
|
|
claim: T; |
|
|
|
claimType?: string; |
|
|
|
} |
|
|
|
export const BLANK_GENERIC_SERVER_RECORD: GenericCredWrapper = { |
|
|
|
export const BLANK_GENERIC_SERVER_RECORD: GenericCredWrapper<GenericVerifiableCredential> = |
|
|
|
{ |
|
|
|
"@context": SCHEMA_ORG_CONTEXT, |
|
|
|
"@type": "", |
|
|
|
claim: {}, |
|
|
|
claim: { "@type": "" }, |
|
|
|
handleId: "", |
|
|
|
id: "", |
|
|
|
issuedAt: "", |
|
|
|
issuer: "", |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
// a summary record; the VC is found the fullClaim field
|
|
|
|
export interface GiveSummaryRecord { |
|
|
@ -123,7 +125,7 @@ export interface PlanSummaryRecord { |
|
|
|
|
|
|
|
// Note that previous VCs may have additional fields.
|
|
|
|
// https://endorser.ch/doc/html/transactions.html#id4
|
|
|
|
export interface GiveVerifiableCredential { |
|
|
|
export interface GiveVerifiableCredential extends GenericVerifiableCredential { |
|
|
|
"@context"?: string; // optional when embedded, eg. in an Agree
|
|
|
|
"@type": "GiveAction"; |
|
|
|
agent?: { identifier: string }; |
|
|
@ -191,7 +193,7 @@ export interface PlanData { |
|
|
|
*/ |
|
|
|
issuerDid: string; |
|
|
|
/** |
|
|
|
* The Identier of the project -- different from jwtId, needs to be fixed |
|
|
|
* The identifier of the project -- different from jwtId, needs to be fixed |
|
|
|
**/ |
|
|
|
rowid?: string; |
|
|
|
} |
|
|
@ -562,8 +564,9 @@ export async function setPlanInCache( |
|
|
|
/** |
|
|
|
* Construct GiveAction VC for submission to server |
|
|
|
*/ |
|
|
|
export function constructGive( |
|
|
|
fromDid?: string | null, |
|
|
|
export function hydrateGive( |
|
|
|
vcClaimOrig?: GiveVerifiableCredential, |
|
|
|
fromDid?: string, |
|
|
|
toDid?: string, |
|
|
|
description?: string, |
|
|
|
amount?: number, |
|
|
@ -572,42 +575,68 @@ export function constructGive( |
|
|
|
fulfillsOfferHandleId?: string, |
|
|
|
isTrade: boolean = false, |
|
|
|
imageUrl?: string, |
|
|
|
lastClaimId?: string, |
|
|
|
): GiveVerifiableCredential { |
|
|
|
const vcClaim: GiveVerifiableCredential = { |
|
|
|
// Remember: replace values or erase if it's null
|
|
|
|
|
|
|
|
const vcClaim: GiveVerifiableCredential = vcClaimOrig |
|
|
|
? R.clone(vcClaimOrig) |
|
|
|
: { |
|
|
|
"@context": SCHEMA_ORG_CONTEXT, |
|
|
|
"@type": "GiveAction", |
|
|
|
recipient: toDid ? { identifier: toDid } : undefined, |
|
|
|
agent: fromDid ? { identifier: fromDid } : undefined, |
|
|
|
description: description || undefined, |
|
|
|
object: amount |
|
|
|
? { amountOfThisGood: amount, unitCode: unitCode || "HUR" } |
|
|
|
: undefined, |
|
|
|
fulfills: [{ "@type": isTrade ? "TradeAction" : "DonateAction" }], |
|
|
|
}; |
|
|
|
|
|
|
|
if (lastClaimId) { |
|
|
|
vcClaim.lastClaimId = lastClaimId; |
|
|
|
delete vcClaim.identifier; |
|
|
|
} |
|
|
|
|
|
|
|
vcClaim.agent = fromDid ? { identifier: fromDid } : undefined; |
|
|
|
vcClaim.recipient = toDid ? { identifier: toDid } : undefined; |
|
|
|
vcClaim.description = description || undefined; |
|
|
|
vcClaim.object = amount |
|
|
|
? { amountOfThisGood: amount, unitCode: unitCode || "HUR" } |
|
|
|
: undefined; |
|
|
|
|
|
|
|
// ensure fulfills is an array
|
|
|
|
if (!Array.isArray(vcClaim.fulfills)) { |
|
|
|
vcClaim.fulfills = vcClaim.fulfills ? [vcClaim.fulfills] : []; |
|
|
|
} |
|
|
|
// ... and replace or add each element, ending with Trade or Donate
|
|
|
|
// I realize this doesn't change any elements that are not PlanAction or Offer or Trade/Action.
|
|
|
|
if (fulfillsProjectHandleId) { |
|
|
|
vcClaim.fulfills = vcClaim.fulfills || []; // weird that it won't typecheck without this
|
|
|
|
vcClaim.fulfills = vcClaim.fulfills.filter( |
|
|
|
(elem) => elem["@type"] !== "PlanAction", |
|
|
|
); |
|
|
|
vcClaim.fulfills.push({ |
|
|
|
"@type": "PlanAction", |
|
|
|
identifier: fulfillsProjectHandleId, |
|
|
|
}); |
|
|
|
} |
|
|
|
if (fulfillsOfferHandleId) { |
|
|
|
vcClaim.fulfills = vcClaim.fulfills || []; // weird that it won't typecheck without this
|
|
|
|
vcClaim.fulfills = vcClaim.fulfills.filter( |
|
|
|
(elem) => elem["@type"] !== "Offer", |
|
|
|
); |
|
|
|
vcClaim.fulfills.push({ |
|
|
|
"@type": "Offer", |
|
|
|
identifier: fulfillsOfferHandleId, |
|
|
|
}); |
|
|
|
} |
|
|
|
if (imageUrl) { |
|
|
|
vcClaim.image = imageUrl; |
|
|
|
} |
|
|
|
// do Trade/Donate last because current endorser.ch only looks at the first for plans & offers
|
|
|
|
vcClaim.fulfills = vcClaim.fulfills.filter( |
|
|
|
(elem) => |
|
|
|
elem["@type"] !== "DonateAction" && elem["@type"] !== "TradeAction", |
|
|
|
); |
|
|
|
vcClaim.fulfills.push({ "@type": isTrade ? "TradeAction" : "DonateAction" }); |
|
|
|
|
|
|
|
vcClaim.image = imageUrl || undefined; |
|
|
|
|
|
|
|
return vcClaim; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* For result, see https://api.endorser.ch/api-docs/#/claims/post_api_v2_claim
|
|
|
|
* |
|
|
|
* @param identity |
|
|
|
* @param fromDid may be null |
|
|
|
* @param toDid |
|
|
|
* @param description may be null; should have this or amount |
|
|
@ -617,7 +646,7 @@ export async function createAndSubmitGive( |
|
|
|
axios: Axios, |
|
|
|
apiServer: string, |
|
|
|
issuerDid: string, |
|
|
|
fromDid?: string | null, |
|
|
|
fromDid?: string, |
|
|
|
toDid?: string, |
|
|
|
description?: string, |
|
|
|
amount?: number, |
|
|
@ -627,7 +656,8 @@ export async function createAndSubmitGive( |
|
|
|
isTrade: boolean = false, |
|
|
|
imageUrl?: string, |
|
|
|
): Promise<CreateAndSubmitClaimResult> { |
|
|
|
const vcClaim = constructGive( |
|
|
|
const vcClaim = hydrateGive( |
|
|
|
undefined, |
|
|
|
fromDid, |
|
|
|
toDid, |
|
|
|
description, |
|
|
@ -639,7 +669,51 @@ export async function createAndSubmitGive( |
|
|
|
imageUrl, |
|
|
|
); |
|
|
|
return createAndSubmitClaim( |
|
|
|
vcClaim as GenericCredWrapper, |
|
|
|
vcClaim as GenericVerifiableCredential, |
|
|
|
issuerDid, |
|
|
|
apiServer, |
|
|
|
axios, |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* For result, see https://api.endorser.ch/api-docs/#/claims/post_api_v2_claim
|
|
|
|
* |
|
|
|
* @param fromDid may be null |
|
|
|
* @param toDid |
|
|
|
* @param description may be null; should have this or amount |
|
|
|
* @param amount may be null; should have this or description |
|
|
|
*/ |
|
|
|
export async function editAndSubmitGive( |
|
|
|
axios: Axios, |
|
|
|
apiServer: string, |
|
|
|
fullClaim: GenericCredWrapper<GiveVerifiableCredential>, |
|
|
|
issuerDid: string, |
|
|
|
fromDid?: string, |
|
|
|
toDid?: string, |
|
|
|
description?: string, |
|
|
|
amount?: number, |
|
|
|
unitCode?: string, |
|
|
|
fulfillsProjectHandleId?: string, |
|
|
|
fulfillsOfferHandleId?: string, |
|
|
|
isTrade: boolean = false, |
|
|
|
imageUrl?: string, |
|
|
|
): Promise<CreateAndSubmitClaimResult> { |
|
|
|
const vcClaim = hydrateGive( |
|
|
|
fullClaim.claim, |
|
|
|
fromDid, |
|
|
|
toDid, |
|
|
|
description, |
|
|
|
amount, |
|
|
|
unitCode, |
|
|
|
fulfillsProjectHandleId, |
|
|
|
fulfillsOfferHandleId, |
|
|
|
isTrade, |
|
|
|
imageUrl, |
|
|
|
fullClaim.id, |
|
|
|
); |
|
|
|
return createAndSubmitClaim( |
|
|
|
vcClaim as GenericVerifiableCredential, |
|
|
|
issuerDid, |
|
|
|
apiServer, |
|
|
|
axios, |
|
|
@ -692,7 +766,7 @@ export async function createAndSubmitOffer( |
|
|
|
}; |
|
|
|
} |
|
|
|
return createAndSubmitClaim( |
|
|
|
vcClaim as GenericCredWrapper, |
|
|
|
vcClaim as OfferVerifiableCredential, |
|
|
|
issuerDid, |
|
|
|
apiServer, |
|
|
|
axios, |
|
|
@ -751,7 +825,7 @@ export async function createAndSubmitClaim( |
|
|
|
return { type: "success", response }; |
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
} catch (error: any) { |
|
|
|
console.error("Error creating claim:", error); |
|
|
|
console.error("Error submitting claim:", error); |
|
|
|
const errorMessage: string = |
|
|
|
error.response?.data?.error?.message || |
|
|
|
error.message || |
|
|
@ -820,24 +894,29 @@ export const capitalizeAndInsertSpacesBeforeCaps = (text: string) => { |
|
|
|
similar code is also contained in endorser-mobile |
|
|
|
**/ |
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
const claimSummary = (claim: Record<string, any>) => { |
|
|
|
const claimSummary = ( |
|
|
|
claim: GenericCredWrapper<GenericVerifiableCredential>, |
|
|
|
) => { |
|
|
|
if (!claim) { |
|
|
|
// to differentiate from "something" above
|
|
|
|
return "something"; |
|
|
|
} |
|
|
|
let specificClaim: |
|
|
|
| GenericVerifiableCredential |
|
|
|
| GenericCredWrapper<GenericVerifiableCredential> = claim; |
|
|
|
if (claim.claim) { |
|
|
|
// probably a Verified Credential
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
claim = claim.claim as Record<string, any>; |
|
|
|
specificClaim = claim.claim; |
|
|
|
} |
|
|
|
if (Array.isArray(claim)) { |
|
|
|
if (claim.length === 1) { |
|
|
|
claim = claim[0]; |
|
|
|
if (Array.isArray(specificClaim)) { |
|
|
|
if (specificClaim.length === 1) { |
|
|
|
specificClaim = specificClaim[0]; |
|
|
|
} else { |
|
|
|
return "multiple claims"; |
|
|
|
} |
|
|
|
} |
|
|
|
const type = claim["@type"]; |
|
|
|
const type = specificClaim["@type"]; |
|
|
|
if (!type) { |
|
|
|
return "a claim"; |
|
|
|
} else { |
|
|
@ -858,7 +937,7 @@ const claimSummary = (claim: Record<string, any>) => { |
|
|
|
similar code is also contained in endorser-mobile |
|
|
|
**/ |
|
|
|
export const claimSpecialDescription = ( |
|
|
|
record: GenericCredWrapper, |
|
|
|
record: GenericCredWrapper<GenericVerifiableCredential>, |
|
|
|
activeDid: string, |
|
|
|
identifiers: Array<string>, |
|
|
|
contacts: Array<Contact>, |
|
|
@ -952,7 +1031,11 @@ export const claimSpecialDescription = ( |
|
|
|
"...]" |
|
|
|
); |
|
|
|
} else { |
|
|
|
return issuer + " declared " + claimSummary(claim as GenericCredWrapper); |
|
|
|
return ( |
|
|
|
issuer + |
|
|
|
" declared " + |
|
|
|
claimSummary(claim as GenericCredWrapper<GenericVerifiableCredential>) |
|
|
|
); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|