vet-data-utils-ts 0.5.3 → 0.5.5
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.
- package/README.md +3 -0
- package/dist/clinical-terminology.d.ts +17 -0
- package/dist/clinical-terminology.js +17 -0
- package/dist/financial.d.ts +64 -0
- package/dist/financial.js +83 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/payment.d.ts +125 -0
- package/dist/payment.js +104 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# vet-data-utils-ts
|
|
2
2
|
|
|
3
|
+
Development and releases follow the mandatory
|
|
4
|
+
[`local-first TDD and release contract`](docs/LOCAL_FIRST_RELEASE_CONTRACT.md).
|
|
5
|
+
|
|
3
6
|
Browser-safe, transport-neutral VetChain data contracts shared by GW VET and
|
|
4
7
|
`vet-sdk-core-ts`. The package owns governed values and validation only; GW VET
|
|
5
8
|
owns authorization and the SDK owns request construction.
|
|
@@ -19,6 +19,23 @@ export declare const VeterinaryTerminologySourceScopes: Readonly<{
|
|
|
19
19
|
readonly Icd10: "ICD10";
|
|
20
20
|
readonly AtcVet: "ATCVET";
|
|
21
21
|
}>;
|
|
22
|
+
/** Deterministic standards-based data for the isolated local terminology upstream. */
|
|
23
|
+
export declare const VET_TERMINOLOGY_TEST_DATA: Readonly<{
|
|
24
|
+
readonly localApiKey: "local-playwright-umls-key";
|
|
25
|
+
readonly bodyTemperature: Readonly<{
|
|
26
|
+
source: "LNC";
|
|
27
|
+
system: "http://loinc.org";
|
|
28
|
+
code: "8310-5";
|
|
29
|
+
display: "Body temperature:Temp:Pt:^Patient:Qn";
|
|
30
|
+
}>;
|
|
31
|
+
readonly otitisExternaSpanish: Readonly<{
|
|
32
|
+
scope: "SNOMED_CT";
|
|
33
|
+
umlsSource: "SCTSPA";
|
|
34
|
+
system: "http://snomed.info/sct";
|
|
35
|
+
code: "3135009";
|
|
36
|
+
display: "otitis externa";
|
|
37
|
+
}>;
|
|
38
|
+
}>;
|
|
22
39
|
export type VeterinaryTerminologySourceScope = typeof VeterinaryTerminologySourceScopes[keyof typeof VeterinaryTerminologySourceScopes];
|
|
23
40
|
export type VeterinaryTerminologyCapability = Readonly<{
|
|
24
41
|
type: 'terminology-capability';
|
|
@@ -19,6 +19,23 @@ export const VeterinaryTerminologySourceScopes = Object.freeze({
|
|
|
19
19
|
Icd10: 'ICD10',
|
|
20
20
|
AtcVet: 'ATCVET',
|
|
21
21
|
});
|
|
22
|
+
/** Deterministic standards-based data for the isolated local terminology upstream. */
|
|
23
|
+
export const VET_TERMINOLOGY_TEST_DATA = Object.freeze({
|
|
24
|
+
localApiKey: 'local-playwright-umls-key',
|
|
25
|
+
bodyTemperature: Object.freeze({
|
|
26
|
+
source: VeterinaryTerminologySourceScopes.Loinc,
|
|
27
|
+
system: VeterinaryClinicalTerminologySystems.Loinc,
|
|
28
|
+
code: '8310-5',
|
|
29
|
+
display: 'Body temperature:Temp:Pt:^Patient:Qn',
|
|
30
|
+
}),
|
|
31
|
+
otitisExternaSpanish: Object.freeze({
|
|
32
|
+
scope: VeterinaryTerminologySourceScopes.SnomedCt,
|
|
33
|
+
umlsSource: 'SCTSPA',
|
|
34
|
+
system: VeterinaryClinicalTerminologySystems.SnomedCt,
|
|
35
|
+
code: '3135009',
|
|
36
|
+
display: 'otitis externa',
|
|
37
|
+
}),
|
|
38
|
+
});
|
|
22
39
|
/**
|
|
23
40
|
* ISO 3166-1 alpha-2 territories enumerated by the official SNOMED
|
|
24
41
|
* International member page on 2026-09-05.
|
package/dist/financial.d.ts
CHANGED
|
@@ -13,6 +13,48 @@ export declare const VeterinaryFinancialResourceTypes: Readonly<{
|
|
|
13
13
|
readonly PaymentReconciliation: "PaymentReconciliation";
|
|
14
14
|
}>;
|
|
15
15
|
export type VeterinaryFinancialResourceType = typeof VeterinaryFinancialResourceTypes[keyof typeof VeterinaryFinancialResourceTypes];
|
|
16
|
+
/** Governed FHIR R5 claim names used by payment reconciliation builders. */
|
|
17
|
+
export declare const VeterinaryPaymentClaimNames: Readonly<{
|
|
18
|
+
readonly Invoice: Readonly<{
|
|
19
|
+
Identifier: "Invoice.identifier";
|
|
20
|
+
Status: "Invoice.status";
|
|
21
|
+
Recipient: "Invoice.recipient";
|
|
22
|
+
Creation: "Invoice.creation";
|
|
23
|
+
TotalGross: "Invoice.total-gross";
|
|
24
|
+
}>;
|
|
25
|
+
readonly PaymentNotice: Readonly<{
|
|
26
|
+
Identifier: "PaymentNotice.identifier";
|
|
27
|
+
Status: "PaymentNotice.status";
|
|
28
|
+
Request: "PaymentNotice.request";
|
|
29
|
+
Created: "PaymentNotice.created";
|
|
30
|
+
Payment: "PaymentNotice.payment";
|
|
31
|
+
PaymentDate: "PaymentNotice.payment-date";
|
|
32
|
+
Recipient: "PaymentNotice.recipient";
|
|
33
|
+
Amount: "PaymentNotice.amount";
|
|
34
|
+
}>;
|
|
35
|
+
readonly PaymentReconciliation: Readonly<{
|
|
36
|
+
Identifier: "PaymentReconciliation.identifier";
|
|
37
|
+
Type: "PaymentReconciliation.type";
|
|
38
|
+
Status: "PaymentReconciliation.status";
|
|
39
|
+
Created: "PaymentReconciliation.created";
|
|
40
|
+
Outcome: "PaymentReconciliation.outcome";
|
|
41
|
+
Date: "PaymentReconciliation.date";
|
|
42
|
+
ReferenceNumber: "PaymentReconciliation.reference-number";
|
|
43
|
+
Amount: "PaymentReconciliation.amount";
|
|
44
|
+
PaymentIdentifier: "PaymentReconciliation.payment-identifier";
|
|
45
|
+
AllocationTarget: "PaymentReconciliation.allocation-target";
|
|
46
|
+
AllocationAmount: "PaymentReconciliation.allocation-amount";
|
|
47
|
+
}>;
|
|
48
|
+
}>;
|
|
49
|
+
export declare const FhirR5FinancialStatusCodes: Readonly<{
|
|
50
|
+
readonly Active: "active";
|
|
51
|
+
readonly InvoiceIssued: "issued";
|
|
52
|
+
readonly ReconciliationComplete: "complete";
|
|
53
|
+
}>;
|
|
54
|
+
export declare const FhirR5PaymentType: Readonly<{
|
|
55
|
+
readonly system: "http://terminology.hl7.org/CodeSystem/payment-type";
|
|
56
|
+
readonly code: "payment";
|
|
57
|
+
}>;
|
|
16
58
|
/** Canonical claim allow-list used before a native FHIR resource is indexed. */
|
|
17
59
|
export declare const VeterinaryFinancialClaimCatalog: Readonly<{
|
|
18
60
|
Account: readonly ["Account.identifier", "Account.status", "Account.billing-status", "Account.type", "Account.name", "Account.subject", "Account.service-period", "Account.coverage-coverage", "Account.coverage-priority", "Account.owner", "Account.description", "Account.guarantor-party", "Account.guarantor-on-hold", "Account.guarantor-period", "Account.diagnosis-sequence", "Account.diagnosis-condition", "Account.diagnosis-date", "Account.diagnosis-type", "Account.diagnosis-on-admission", "Account.diagnosis-package-code", "Account.procedure-sequence", "Account.procedure-code", "Account.procedure-date-of-service", "Account.procedure-type", "Account.procedure-package-code", "Account.procedure-device", "Account.related-account-account", "Account.related-account-relationship", "Account.currency", "Account.balance-aggregate", "Account.balance-term", "Account.balance-estimate", "Account.balance-amount", "Account.calculated-at"];
|
|
@@ -24,3 +66,25 @@ export declare const VeterinaryFinancialClaimCatalog: Readonly<{
|
|
|
24
66
|
export declare function getVeterinaryFinancialClaims(resourceType: unknown): readonly string[];
|
|
25
67
|
/** Checks both the resource family and its claim prefix/allow-list. */
|
|
26
68
|
export declare function isVeterinaryFinancialClaim(resourceType: unknown, claim: unknown): boolean;
|
|
69
|
+
export type ClaimsFirstFinancialResource<T extends VeterinaryFinancialResourceType> = Readonly<{
|
|
70
|
+
resourceType: T;
|
|
71
|
+
id: string;
|
|
72
|
+
meta: Readonly<{
|
|
73
|
+
claims: Readonly<Record<string, unknown>>;
|
|
74
|
+
}>;
|
|
75
|
+
}>;
|
|
76
|
+
/**
|
|
77
|
+
* Projects verified provider evidence into standard FHIR R5 financial claims.
|
|
78
|
+
* Provider references use existing FHIR elements and never extend the catalog.
|
|
79
|
+
*/
|
|
80
|
+
export type EvmTransferFinancialReconciliation = Readonly<{
|
|
81
|
+
invoice: ClaimsFirstFinancialResource<'Invoice'>;
|
|
82
|
+
paymentNotice: ClaimsFirstFinancialResource<'PaymentNotice'>;
|
|
83
|
+
paymentReconciliation: ClaimsFirstFinancialResource<'PaymentReconciliation'>;
|
|
84
|
+
}>;
|
|
85
|
+
export declare function buildEvmTransferFinancialReconciliation(input: Readonly<{
|
|
86
|
+
quote: import('./payment.js').EvmTransferPaymentQuote;
|
|
87
|
+
transactionHash: `0x${string}`;
|
|
88
|
+
verifiedAt: string;
|
|
89
|
+
recipientReference: string;
|
|
90
|
+
}>): EvmTransferFinancialReconciliation;
|
package/dist/financial.js
CHANGED
|
@@ -12,6 +12,33 @@ export const VeterinaryFinancialResourceTypes = Object.freeze({
|
|
|
12
12
|
PaymentNotice: 'PaymentNotice',
|
|
13
13
|
PaymentReconciliation: 'PaymentReconciliation',
|
|
14
14
|
});
|
|
15
|
+
/** Governed FHIR R5 claim names used by payment reconciliation builders. */
|
|
16
|
+
export const VeterinaryPaymentClaimNames = Object.freeze({
|
|
17
|
+
Invoice: Object.freeze({
|
|
18
|
+
Identifier: 'Invoice.identifier', Status: 'Invoice.status', Recipient: 'Invoice.recipient',
|
|
19
|
+
Creation: 'Invoice.creation', TotalGross: 'Invoice.total-gross',
|
|
20
|
+
}),
|
|
21
|
+
PaymentNotice: Object.freeze({
|
|
22
|
+
Identifier: 'PaymentNotice.identifier', Status: 'PaymentNotice.status', Request: 'PaymentNotice.request',
|
|
23
|
+
Created: 'PaymentNotice.created', Payment: 'PaymentNotice.payment', PaymentDate: 'PaymentNotice.payment-date',
|
|
24
|
+
Recipient: 'PaymentNotice.recipient', Amount: 'PaymentNotice.amount',
|
|
25
|
+
}),
|
|
26
|
+
PaymentReconciliation: Object.freeze({
|
|
27
|
+
Identifier: 'PaymentReconciliation.identifier', Type: 'PaymentReconciliation.type',
|
|
28
|
+
Status: 'PaymentReconciliation.status', Created: 'PaymentReconciliation.created',
|
|
29
|
+
Outcome: 'PaymentReconciliation.outcome', Date: 'PaymentReconciliation.date',
|
|
30
|
+
ReferenceNumber: 'PaymentReconciliation.reference-number', Amount: 'PaymentReconciliation.amount',
|
|
31
|
+
PaymentIdentifier: 'PaymentReconciliation.payment-identifier',
|
|
32
|
+
AllocationTarget: 'PaymentReconciliation.allocation-target',
|
|
33
|
+
AllocationAmount: 'PaymentReconciliation.allocation-amount',
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
export const FhirR5FinancialStatusCodes = Object.freeze({
|
|
37
|
+
Active: 'active', InvoiceIssued: 'issued', ReconciliationComplete: 'complete',
|
|
38
|
+
});
|
|
39
|
+
export const FhirR5PaymentType = Object.freeze({
|
|
40
|
+
system: 'http://terminology.hl7.org/CodeSystem/payment-type', code: 'payment',
|
|
41
|
+
});
|
|
15
42
|
const accountClaims = Object.freeze([
|
|
16
43
|
'Account.identifier',
|
|
17
44
|
'Account.status',
|
|
@@ -160,3 +187,59 @@ export function isVeterinaryFinancialClaim(resourceType, claim) {
|
|
|
160
187
|
function isVeterinaryFinancialResourceType(value) {
|
|
161
188
|
return Object.values(VeterinaryFinancialResourceTypes).includes(value);
|
|
162
189
|
}
|
|
190
|
+
function usdcMoney(amountMinor) {
|
|
191
|
+
const padded = amountMinor.padStart(7, '0');
|
|
192
|
+
const split = padded.length - 6;
|
|
193
|
+
return { value: `${padded.slice(0, split)}.${padded.slice(split)}`, currency: 'USD' };
|
|
194
|
+
}
|
|
195
|
+
export function buildEvmTransferFinancialReconciliation(input) {
|
|
196
|
+
const paymentNoticeId = input.quote.paymentReference;
|
|
197
|
+
const paymentReconciliationId = input.quote.paymentReference;
|
|
198
|
+
const invoiceReference = `Invoice/${input.quote.invoiceId}`;
|
|
199
|
+
const reconciliationReference = `PaymentReconciliation/${paymentReconciliationId}`;
|
|
200
|
+
const money = usdcMoney(input.quote.amountMinor);
|
|
201
|
+
return {
|
|
202
|
+
invoice: {
|
|
203
|
+
resourceType: VeterinaryFinancialResourceTypes.Invoice,
|
|
204
|
+
id: input.quote.invoiceId,
|
|
205
|
+
meta: { claims: {
|
|
206
|
+
[VeterinaryPaymentClaimNames.Invoice.Identifier]: input.quote.paymentReference,
|
|
207
|
+
[VeterinaryPaymentClaimNames.Invoice.Status]: FhirR5FinancialStatusCodes.InvoiceIssued,
|
|
208
|
+
[VeterinaryPaymentClaimNames.Invoice.Recipient]: input.recipientReference,
|
|
209
|
+
[VeterinaryPaymentClaimNames.Invoice.Creation]: input.quote.createdAt,
|
|
210
|
+
[VeterinaryPaymentClaimNames.Invoice.TotalGross]: money,
|
|
211
|
+
} },
|
|
212
|
+
},
|
|
213
|
+
paymentNotice: {
|
|
214
|
+
resourceType: VeterinaryFinancialResourceTypes.PaymentNotice,
|
|
215
|
+
id: paymentNoticeId,
|
|
216
|
+
meta: { claims: {
|
|
217
|
+
[VeterinaryPaymentClaimNames.PaymentNotice.Identifier]: input.quote.paymentReference,
|
|
218
|
+
[VeterinaryPaymentClaimNames.PaymentNotice.Status]: FhirR5FinancialStatusCodes.Active,
|
|
219
|
+
[VeterinaryPaymentClaimNames.PaymentNotice.Request]: invoiceReference,
|
|
220
|
+
[VeterinaryPaymentClaimNames.PaymentNotice.Created]: input.verifiedAt,
|
|
221
|
+
[VeterinaryPaymentClaimNames.PaymentNotice.Payment]: reconciliationReference,
|
|
222
|
+
[VeterinaryPaymentClaimNames.PaymentNotice.PaymentDate]: input.verifiedAt.slice(0, 10),
|
|
223
|
+
[VeterinaryPaymentClaimNames.PaymentNotice.Recipient]: input.recipientReference,
|
|
224
|
+
[VeterinaryPaymentClaimNames.PaymentNotice.Amount]: money,
|
|
225
|
+
} },
|
|
226
|
+
},
|
|
227
|
+
paymentReconciliation: {
|
|
228
|
+
resourceType: VeterinaryFinancialResourceTypes.PaymentReconciliation,
|
|
229
|
+
id: paymentReconciliationId,
|
|
230
|
+
meta: { claims: {
|
|
231
|
+
[VeterinaryPaymentClaimNames.PaymentReconciliation.Identifier]: input.quote.paymentReference,
|
|
232
|
+
[VeterinaryPaymentClaimNames.PaymentReconciliation.Type]: { coding: [FhirR5PaymentType] },
|
|
233
|
+
[VeterinaryPaymentClaimNames.PaymentReconciliation.Status]: FhirR5FinancialStatusCodes.Active,
|
|
234
|
+
[VeterinaryPaymentClaimNames.PaymentReconciliation.Created]: input.verifiedAt,
|
|
235
|
+
[VeterinaryPaymentClaimNames.PaymentReconciliation.Outcome]: FhirR5FinancialStatusCodes.ReconciliationComplete,
|
|
236
|
+
[VeterinaryPaymentClaimNames.PaymentReconciliation.Date]: input.verifiedAt.slice(0, 10),
|
|
237
|
+
[VeterinaryPaymentClaimNames.PaymentReconciliation.ReferenceNumber]: input.transactionHash,
|
|
238
|
+
[VeterinaryPaymentClaimNames.PaymentReconciliation.Amount]: money,
|
|
239
|
+
[VeterinaryPaymentClaimNames.PaymentReconciliation.PaymentIdentifier]: input.quote.paymentReference,
|
|
240
|
+
[VeterinaryPaymentClaimNames.PaymentReconciliation.AllocationTarget]: invoiceReference,
|
|
241
|
+
[VeterinaryPaymentClaimNames.PaymentReconciliation.AllocationAmount]: money,
|
|
242
|
+
} },
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from './financial.js';
|
|
|
8
8
|
export * from './group.js';
|
|
9
9
|
export * from './iso-jurisdictions.js';
|
|
10
10
|
export * from './organization-application.js';
|
|
11
|
+
export * from './payment.js';
|
|
11
12
|
export * from './research-study.js';
|
|
12
13
|
export * from './sectors.js';
|
|
13
14
|
export * from './veterinary-sections.js';
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export * from './financial.js';
|
|
|
8
8
|
export * from './group.js';
|
|
9
9
|
export * from './iso-jurisdictions.js';
|
|
10
10
|
export * from './organization-application.js';
|
|
11
|
+
export * from './payment.js';
|
|
11
12
|
export * from './research-study.js';
|
|
12
13
|
export * from './sectors.js';
|
|
13
14
|
export * from './veterinary-sections.js';
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/** Provider and asset identifiers for VetChain payment adapters. */
|
|
2
|
+
export declare const PaymentProviderIds: Readonly<{
|
|
3
|
+
readonly Stripe: "STRIPE";
|
|
4
|
+
readonly EvmTransfer: "EVM_TRANSFER";
|
|
5
|
+
}>;
|
|
6
|
+
export declare const PaymentAssetIds: Readonly<{
|
|
7
|
+
readonly Usdc: "USDC";
|
|
8
|
+
}>;
|
|
9
|
+
export declare const PaymentCurrencyCodes: Readonly<{
|
|
10
|
+
readonly Usd: "USD";
|
|
11
|
+
}>;
|
|
12
|
+
export declare const USDC_DECIMALS: 6;
|
|
13
|
+
export declare const PaymentFlowActions: Readonly<{
|
|
14
|
+
readonly Quote: "quote";
|
|
15
|
+
readonly Confirm: "confirm";
|
|
16
|
+
}>;
|
|
17
|
+
export type PaymentFlowAction = typeof PaymentFlowActions[keyof typeof PaymentFlowActions];
|
|
18
|
+
export type EvmTransferPaymentConfirmation = Readonly<{
|
|
19
|
+
offerId: string;
|
|
20
|
+
transactionHash: `0x${string}`;
|
|
21
|
+
}>;
|
|
22
|
+
export declare const EvmPaymentNetworkIds: Readonly<{
|
|
23
|
+
readonly LocalAnvil: "local-anvil";
|
|
24
|
+
readonly BaseSepolia: "base-sepolia";
|
|
25
|
+
readonly BaseMainnet: "base-mainnet";
|
|
26
|
+
}>;
|
|
27
|
+
export type PaymentProviderId = typeof PaymentProviderIds[keyof typeof PaymentProviderIds];
|
|
28
|
+
export type EvmPaymentNetworkId = typeof EvmPaymentNetworkIds[keyof typeof EvmPaymentNetworkIds];
|
|
29
|
+
export type EvmTransferNetwork = Readonly<{
|
|
30
|
+
id: EvmPaymentNetworkId;
|
|
31
|
+
chainId: number;
|
|
32
|
+
asset: typeof PaymentAssetIds.Usdc;
|
|
33
|
+
tokenContract: `0x${string}`;
|
|
34
|
+
mainnet: boolean;
|
|
35
|
+
}>;
|
|
36
|
+
/** Circle-issued native USDC contracts for Base. */
|
|
37
|
+
export declare const USDC_BASE_NETWORKS: Readonly<{
|
|
38
|
+
"base-sepolia": Readonly<{
|
|
39
|
+
id: "base-sepolia";
|
|
40
|
+
chainId: 84532;
|
|
41
|
+
asset: "USDC";
|
|
42
|
+
tokenContract: "0x036CbD53842c5426634e7929541eC2318f3dCF7e";
|
|
43
|
+
mainnet: false;
|
|
44
|
+
}>;
|
|
45
|
+
"base-mainnet": Readonly<{
|
|
46
|
+
id: "base-mainnet";
|
|
47
|
+
chainId: 8453;
|
|
48
|
+
asset: "USDC";
|
|
49
|
+
tokenContract: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
50
|
+
mainnet: true;
|
|
51
|
+
}>;
|
|
52
|
+
}>;
|
|
53
|
+
export type EvmTransferPaymentQuote = Readonly<{
|
|
54
|
+
version: 1;
|
|
55
|
+
provider: typeof PaymentProviderIds.EvmTransfer;
|
|
56
|
+
asset: typeof PaymentAssetIds.Usdc;
|
|
57
|
+
paymentReference: string;
|
|
58
|
+
invoiceId: string;
|
|
59
|
+
offerId: string;
|
|
60
|
+
network: EvmPaymentNetworkId;
|
|
61
|
+
chainId: number;
|
|
62
|
+
tokenContract: `0x${string}`;
|
|
63
|
+
recipient: `0x${string}`;
|
|
64
|
+
amountMinor: string;
|
|
65
|
+
decimals: typeof USDC_DECIMALS;
|
|
66
|
+
createdAt: string;
|
|
67
|
+
expiresAt: string;
|
|
68
|
+
expectedPayer?: `0x${string}`;
|
|
69
|
+
}>;
|
|
70
|
+
/** Reusable deterministic values for package, GW, BFF and browser tests. */
|
|
71
|
+
export declare const VET_PAYMENT_TEST_DATA: Readonly<{
|
|
72
|
+
readonly recipient: "0x1111111111111111111111111111111111111111";
|
|
73
|
+
readonly otherRecipient: "0x2222222222222222222222222222222222222222";
|
|
74
|
+
readonly payer: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266";
|
|
75
|
+
readonly localPayerPrivateKey: "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
|
|
76
|
+
readonly localUsdcContract: "0x5FbDB2315678afecb367f032d93F642f64180aa3";
|
|
77
|
+
readonly localRpcUrl: "http://127.0.0.1:3270";
|
|
78
|
+
readonly transactionHash: `0x${string}`;
|
|
79
|
+
readonly otherTransactionHash: `0x${string}`;
|
|
80
|
+
readonly amountMinor: 10000000n;
|
|
81
|
+
readonly amountMinorText: "10000000";
|
|
82
|
+
readonly zeroPriceText: "0";
|
|
83
|
+
readonly invalidAmountMinorText: "10.5";
|
|
84
|
+
readonly invalidOfferPriceText: "10.0000001";
|
|
85
|
+
readonly decimals: 6;
|
|
86
|
+
readonly priceText: "10";
|
|
87
|
+
readonly currency: "USD";
|
|
88
|
+
readonly localChainId: 31337;
|
|
89
|
+
readonly receiptBlockNumber: 100n;
|
|
90
|
+
readonly confirmedBlockNumber: 102n;
|
|
91
|
+
readonly minimumConfirmations: 3;
|
|
92
|
+
readonly quantity: 1;
|
|
93
|
+
readonly localPurchaseQuantity: 3;
|
|
94
|
+
readonly paymentReference: "pay_test_01";
|
|
95
|
+
readonly invoiceId: "invoice_test_01";
|
|
96
|
+
readonly offerId: "offer_test_01";
|
|
97
|
+
readonly ownerId: "payment_owner_test_01";
|
|
98
|
+
readonly profileId: "payment_profile_test_01";
|
|
99
|
+
readonly recipientOrganizationReference: "Organization/payment-recipient-test";
|
|
100
|
+
readonly validAt: "2026-09-07T12:00:00.000Z";
|
|
101
|
+
readonly expiresAt: "2026-09-07T12:10:00.000Z";
|
|
102
|
+
readonly expiredAt: "2026-09-07T12:11:00.000Z";
|
|
103
|
+
readonly quote: Readonly<{
|
|
104
|
+
version: 1;
|
|
105
|
+
provider: "EVM_TRANSFER";
|
|
106
|
+
asset: "USDC";
|
|
107
|
+
paymentReference: string;
|
|
108
|
+
invoiceId: string;
|
|
109
|
+
offerId: string;
|
|
110
|
+
network: "local-anvil";
|
|
111
|
+
chainId: number;
|
|
112
|
+
tokenContract: "0x5FbDB2315678afecb367f032d93F642f64180aa3";
|
|
113
|
+
recipient: "0x1111111111111111111111111111111111111111";
|
|
114
|
+
amountMinor: string;
|
|
115
|
+
decimals: 6;
|
|
116
|
+
createdAt: string;
|
|
117
|
+
expiresAt: string;
|
|
118
|
+
expectedPayer: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266";
|
|
119
|
+
}>;
|
|
120
|
+
}>;
|
|
121
|
+
export declare function usdOfferToUsdcMinor(input: Readonly<{
|
|
122
|
+
price: unknown;
|
|
123
|
+
priceCurrency: unknown;
|
|
124
|
+
quantity: unknown;
|
|
125
|
+
}>): bigint;
|
package/dist/payment.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Provider and asset identifiers for VetChain payment adapters. */
|
|
2
|
+
export const PaymentProviderIds = Object.freeze({
|
|
3
|
+
Stripe: 'STRIPE',
|
|
4
|
+
EvmTransfer: 'EVM_TRANSFER',
|
|
5
|
+
});
|
|
6
|
+
export const PaymentAssetIds = Object.freeze({ Usdc: 'USDC' });
|
|
7
|
+
export const PaymentCurrencyCodes = Object.freeze({ Usd: 'USD' });
|
|
8
|
+
export const USDC_DECIMALS = 6;
|
|
9
|
+
export const PaymentFlowActions = Object.freeze({
|
|
10
|
+
Quote: 'quote',
|
|
11
|
+
Confirm: 'confirm',
|
|
12
|
+
});
|
|
13
|
+
export const EvmPaymentNetworkIds = Object.freeze({
|
|
14
|
+
LocalAnvil: 'local-anvil',
|
|
15
|
+
BaseSepolia: 'base-sepolia',
|
|
16
|
+
BaseMainnet: 'base-mainnet',
|
|
17
|
+
});
|
|
18
|
+
/** Circle-issued native USDC contracts for Base. */
|
|
19
|
+
export const USDC_BASE_NETWORKS = Object.freeze({
|
|
20
|
+
[EvmPaymentNetworkIds.BaseSepolia]: Object.freeze({
|
|
21
|
+
id: EvmPaymentNetworkIds.BaseSepolia,
|
|
22
|
+
chainId: 84532,
|
|
23
|
+
asset: PaymentAssetIds.Usdc,
|
|
24
|
+
tokenContract: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
|
|
25
|
+
mainnet: false,
|
|
26
|
+
}),
|
|
27
|
+
[EvmPaymentNetworkIds.BaseMainnet]: Object.freeze({
|
|
28
|
+
id: EvmPaymentNetworkIds.BaseMainnet,
|
|
29
|
+
chainId: 8453,
|
|
30
|
+
asset: PaymentAssetIds.Usdc,
|
|
31
|
+
tokenContract: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
32
|
+
mainnet: true,
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
/** Reusable deterministic values for package, GW, BFF and browser tests. */
|
|
36
|
+
export const VET_PAYMENT_TEST_DATA = Object.freeze({
|
|
37
|
+
recipient: '0x1111111111111111111111111111111111111111',
|
|
38
|
+
otherRecipient: '0x2222222222222222222222222222222222222222',
|
|
39
|
+
payer: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
|
|
40
|
+
localPayerPrivateKey: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
|
|
41
|
+
localUsdcContract: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
|
|
42
|
+
localRpcUrl: 'http://127.0.0.1:3270',
|
|
43
|
+
transactionHash: `0x${'a'.repeat(64)}`,
|
|
44
|
+
otherTransactionHash: `0x${'b'.repeat(64)}`,
|
|
45
|
+
amountMinor: 10000000n,
|
|
46
|
+
amountMinorText: '10000000',
|
|
47
|
+
zeroPriceText: '0',
|
|
48
|
+
invalidAmountMinorText: '10.5',
|
|
49
|
+
invalidOfferPriceText: '10.0000001',
|
|
50
|
+
decimals: USDC_DECIMALS,
|
|
51
|
+
priceText: '10',
|
|
52
|
+
currency: PaymentCurrencyCodes.Usd,
|
|
53
|
+
localChainId: 31337,
|
|
54
|
+
receiptBlockNumber: 100n,
|
|
55
|
+
confirmedBlockNumber: 102n,
|
|
56
|
+
minimumConfirmations: 3,
|
|
57
|
+
quantity: 1,
|
|
58
|
+
localPurchaseQuantity: 3,
|
|
59
|
+
paymentReference: 'pay_test_01',
|
|
60
|
+
invoiceId: 'invoice_test_01',
|
|
61
|
+
offerId: 'offer_test_01',
|
|
62
|
+
ownerId: 'payment_owner_test_01',
|
|
63
|
+
profileId: 'payment_profile_test_01',
|
|
64
|
+
recipientOrganizationReference: 'Organization/payment-recipient-test',
|
|
65
|
+
validAt: '2026-09-07T12:00:00.000Z',
|
|
66
|
+
expiresAt: '2026-09-07T12:10:00.000Z',
|
|
67
|
+
expiredAt: '2026-09-07T12:11:00.000Z',
|
|
68
|
+
quote: Object.freeze({
|
|
69
|
+
version: 1,
|
|
70
|
+
provider: PaymentProviderIds.EvmTransfer,
|
|
71
|
+
asset: PaymentAssetIds.Usdc,
|
|
72
|
+
paymentReference: 'pay_test_01',
|
|
73
|
+
invoiceId: 'invoice_test_01',
|
|
74
|
+
offerId: 'offer_test_01',
|
|
75
|
+
network: EvmPaymentNetworkIds.LocalAnvil,
|
|
76
|
+
chainId: 31337,
|
|
77
|
+
tokenContract: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
|
|
78
|
+
recipient: '0x1111111111111111111111111111111111111111',
|
|
79
|
+
amountMinor: '10000000',
|
|
80
|
+
decimals: USDC_DECIMALS,
|
|
81
|
+
createdAt: '2026-09-07T12:00:00.000Z',
|
|
82
|
+
expiresAt: '2026-09-07T12:10:00.000Z',
|
|
83
|
+
expectedPayer: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
|
|
84
|
+
}),
|
|
85
|
+
});
|
|
86
|
+
export function usdOfferToUsdcMinor(input) {
|
|
87
|
+
if (String(input.priceCurrency || '').trim().toUpperCase() !== PaymentCurrencyCodes.Usd) {
|
|
88
|
+
throw new Error('usdc_offer_currency_invalid');
|
|
89
|
+
}
|
|
90
|
+
const price = String(input.price || '').trim();
|
|
91
|
+
if (!/^(?:0|[1-9][0-9]*)(?:\.[0-9]{1,6})?$/.test(price)) {
|
|
92
|
+
throw new Error('usdc_offer_amount_invalid');
|
|
93
|
+
}
|
|
94
|
+
const quantity = Number(input.quantity);
|
|
95
|
+
if (!Number.isSafeInteger(quantity) || quantity < 1) {
|
|
96
|
+
throw new Error('usdc_offer_quantity_invalid');
|
|
97
|
+
}
|
|
98
|
+
const [whole, fraction = ''] = price.split('.');
|
|
99
|
+
const unitAmountMinor = BigInt(whole) * 1000000n + BigInt(fraction.padEnd(6, '0'));
|
|
100
|
+
if (unitAmountMinor <= 0n) {
|
|
101
|
+
throw new Error('usdc_offer_amount_invalid');
|
|
102
|
+
}
|
|
103
|
+
return unitAmountMinor * BigInt(quantity);
|
|
104
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vet-data-utils-ts",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"description": "Browser-safe governed VetChain data contracts",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Connecting Solution & Applications Ltd",
|
|
@@ -48,6 +48,10 @@
|
|
|
48
48
|
"types": "./dist/organization-application.d.ts",
|
|
49
49
|
"default": "./dist/organization-application.js"
|
|
50
50
|
},
|
|
51
|
+
"./payment": {
|
|
52
|
+
"types": "./dist/payment.d.ts",
|
|
53
|
+
"default": "./dist/payment.js"
|
|
54
|
+
},
|
|
51
55
|
"./research-study": {
|
|
52
56
|
"types": "./dist/research-study.d.ts",
|
|
53
57
|
"default": "./dist/research-study.js"
|