@mnd8t/sdk 0.1.2 → 0.3.1
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/LICENSE +21 -21
- package/README.md +130 -65
- package/dist/ap2.d.ts +104 -0
- package/dist/ap2.js +88 -0
- package/dist/ap2.js.map +1 -0
- package/dist/client.d.ts +39 -9
- package/dist/client.js +50 -14
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/record.d.ts +25 -0
- package/dist/record.js +117 -0
- package/dist/record.js.map +1 -0
- package/dist/types.d.ts +146 -0
- package/dist/verify.d.ts +1 -0
- package/dist/verify.js +1 -1
- package/dist/verify.js.map +1 -1
- package/package.json +46 -46
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Glencorse Ltd
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Glencorse Ltd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,65 +1,130 @@
|
|
|
1
|
-
# @mnd8t/sdk
|
|
2
|
-
|
|
3
|
-
A typed TypeScript client for the [mnd8t](https://mnd8t.com) authority API.
|
|
4
|
-
|
|
5
|
-
mnd8t decides whether a proposed financial action falls within authority you
|
|
6
|
-
defined, and records signed evidence of that decision. It holds no funds, no
|
|
7
|
-
payment credentials and no private keys — you, or a provider you choose,
|
|
8
|
-
execute every action.
|
|
9
|
-
|
|
10
|
-
No runtime dependencies. Node 22 or newer.
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
npm install @mnd8t/sdk
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## Usage
|
|
17
|
-
|
|
18
|
-
```ts
|
|
19
|
-
import { MandateClient } from "@mnd8t/sdk";
|
|
20
|
-
|
|
21
|
-
const mandate = new MandateClient({
|
|
22
|
-
apiKey: process.env.MANDATE_API_KEY!,
|
|
23
|
-
baseUrl: process.env.MANDATE_API_URL!, // your workspace URL, from the dashboard
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const decision = await mandate.decisions.authorize({
|
|
27
|
-
agent_external_id: "procurement_agent_12",
|
|
28
|
-
amount: { asset: "USDC", asset_amount_minor: 675_000_000 },
|
|
29
|
-
valuation: { policy_amount_minor: 50_000, policy_currency: "GBP", source: "CUSTOMER_SYSTEM" },
|
|
30
|
-
counterparty_external_id: "supplier_acme_cloud",
|
|
31
|
-
purpose: "cloud_infrastructure",
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
if (decision.effective_decision === "APPROVE") {
|
|
35
|
-
// Execute with your own credentials, then confirm.
|
|
36
|
-
} else if (decision.effective_decision === "ESCALATE") {
|
|
37
|
-
console.log("send this to a human:", decision.approval?.approval_url);
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
There is no shared public endpoint: `baseUrl` is the URL of your own
|
|
42
|
-
workspace, shown in the dashboard. Omit it and the client talks to
|
|
43
|
-
`http://localhost:4000`, which is what `pnpm dev` serves locally.
|
|
44
|
-
|
|
45
|
-
Every decision returns `APPROVE`, `REJECT` or `ESCALATE` with a rule-by-rule
|
|
46
|
-
trace, and produces an Ed25519-signed, hash-chained
|
|
47
|
-
verify without calling us
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
1
|
+
# @mnd8t/sdk
|
|
2
|
+
|
|
3
|
+
A typed TypeScript client for the [mnd8t](https://mnd8t.com) authority API.
|
|
4
|
+
|
|
5
|
+
mnd8t decides whether a proposed financial action falls within authority you
|
|
6
|
+
defined, and records signed evidence of that decision. It holds no funds, no
|
|
7
|
+
payment credentials and no private keys — you, or a provider you choose,
|
|
8
|
+
execute every action.
|
|
9
|
+
|
|
10
|
+
No runtime dependencies. Node 22 or newer.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @mnd8t/sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { MandateClient } from "@mnd8t/sdk";
|
|
20
|
+
|
|
21
|
+
const mandate = new MandateClient({
|
|
22
|
+
apiKey: process.env.MANDATE_API_KEY!,
|
|
23
|
+
baseUrl: process.env.MANDATE_API_URL!, // your workspace URL, from the dashboard
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const decision = await mandate.decisions.authorize({
|
|
27
|
+
agent_external_id: "procurement_agent_12",
|
|
28
|
+
amount: { asset: "USDC", asset_amount_minor: 675_000_000 },
|
|
29
|
+
valuation: { policy_amount_minor: 50_000, policy_currency: "GBP", source: "CUSTOMER_SYSTEM" },
|
|
30
|
+
counterparty_external_id: "supplier_acme_cloud",
|
|
31
|
+
purpose: "cloud_infrastructure",
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (decision.effective_decision === "APPROVE") {
|
|
35
|
+
// Execute with your own credentials, then confirm.
|
|
36
|
+
} else if (decision.effective_decision === "ESCALATE") {
|
|
37
|
+
console.log("send this to a human:", decision.approval?.approval_url);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
There is no shared public endpoint: `baseUrl` is the URL of your own
|
|
42
|
+
workspace, shown in the dashboard. Omit it and the client talks to
|
|
43
|
+
`http://localhost:4000`, which is what `pnpm dev` serves locally.
|
|
44
|
+
|
|
45
|
+
Every decision returns `APPROVE`, `REJECT` or `ESCALATE` with a rule-by-rule
|
|
46
|
+
trace, and produces an Authority Record: an Ed25519-signed, hash-chained
|
|
47
|
+
evidence receipt you can verify without calling us.
|
|
48
|
+
|
|
49
|
+
## Verifying an Authority Record
|
|
50
|
+
|
|
51
|
+
The record carries an `action_hash`, a digest of the exact action that was
|
|
52
|
+
evaluated. An executor can check that the record it was handed authorises the
|
|
53
|
+
payment it is about to make, and not a similar one:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { MandateClient, actionDigest } from "@mnd8t/sdk";
|
|
57
|
+
|
|
58
|
+
const mandate = new MandateClient({ apiKey: process.env.MANDATE_API_KEY!, baseUrl: process.env.MANDATE_API_URL! });
|
|
59
|
+
|
|
60
|
+
const instruction = {
|
|
61
|
+
action_type: "PAYMENT",
|
|
62
|
+
financial_account_id: null,
|
|
63
|
+
asset: "GBP",
|
|
64
|
+
amount_minor: 500_000,
|
|
65
|
+
counterparty: "supplier_a",
|
|
66
|
+
destination: null,
|
|
67
|
+
purpose: "invoice_payment",
|
|
68
|
+
external_reference: "INV-123",
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const decision = await mandate.decisions.authorize({
|
|
72
|
+
agent_external_id: "procurement_agent_12",
|
|
73
|
+
amount: { asset: "GBP", asset_amount_minor: 500_000 },
|
|
74
|
+
valuation: { policy_amount_minor: 500_000, policy_currency: "GBP" },
|
|
75
|
+
counterparty_external_id: "supplier_a",
|
|
76
|
+
purpose: "invoice_payment",
|
|
77
|
+
external_reference: "INV-123",
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const record = decision.authority_record;
|
|
81
|
+
if (record && record.action_hash === (await actionDigest(instruction))) {
|
|
82
|
+
const { receipt } = await mandate.receipts.get(record.receipt_id);
|
|
83
|
+
const result = await mandate.receipts.verify(receipt, { expectedAction: instruction });
|
|
84
|
+
console.log(result.valid, result.signature_valid, result.record_integrity, result.action_match);
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
A valid record proves what mnd8t decided at the time. It does not mean the
|
|
89
|
+
agent is still authorised: `receipts.verifyPresented(receipt)` reports the
|
|
90
|
+
mandate's current state separately.
|
|
91
|
+
|
|
92
|
+
## Checking an AP2 payment against its Authority Record
|
|
93
|
+
|
|
94
|
+
If you hold an AP2 payment (the open and closed Payment Mandates) and the
|
|
95
|
+
Authority Record of the mnd8t decision behind it, check that they describe
|
|
96
|
+
the same payment. Run AP2's own signature and constraint checks first.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { MandateClient, verifyAp2PaymentAgainstRecord, type Ap2PaymentMandate } from "@mnd8t/sdk";
|
|
100
|
+
|
|
101
|
+
const mandate = new MandateClient({ apiKey: process.env.MANDATE_API_KEY!, baseUrl: process.env.MANDATE_API_URL! });
|
|
102
|
+
|
|
103
|
+
declare const openMandate: Record<string, unknown>; // the user-signed open Payment Mandate's claims
|
|
104
|
+
declare const closedMandate: Ap2PaymentMandate; // the agent-signed closed Payment Mandate's claims
|
|
105
|
+
declare const record: Record<string, unknown>; // the Authority Record presented with it
|
|
106
|
+
|
|
107
|
+
const keys = await mandate.receipts.keys();
|
|
108
|
+
const check = await verifyAp2PaymentAgainstRecord({ openMandate, closedMandate, record, keys });
|
|
109
|
+
if (!check.valid) console.log(check.mismatches);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
AP2 support is adapter v0.1, written against AP2 v0.2.0. It is a versioned
|
|
113
|
+
mapping, not certified AP2 conformance.
|
|
114
|
+
|
|
115
|
+
## Documentation
|
|
116
|
+
|
|
117
|
+
- [SDK reference](https://mnd8t.com/docs/sdk) — every method, type and error
|
|
118
|
+
- [Quickstart](https://mnd8t.com/docs/quickstart) — first decision in under 30 minutes
|
|
119
|
+
- [Developer guide](https://mnd8t.com/docs/developer-guide) — the full integration path
|
|
120
|
+
- [Evidence receipts](https://mnd8t.com/docs/evidence-receipts) — format and verification
|
|
121
|
+
|
|
122
|
+
## Support
|
|
123
|
+
|
|
124
|
+
mnd8t is in early access. Speak to your account contact, or report a security
|
|
125
|
+
issue under the [responsible disclosure
|
|
126
|
+
policy](https://mnd8t.com/legal/responsible-disclosure).
|
|
127
|
+
|
|
128
|
+
## Licence
|
|
129
|
+
|
|
130
|
+
MIT © Glencorse Ltd
|
package/dist/ap2.d.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { AuthorityRecordVerification, AuthorizeRequest, VerificationKey } from "./types.js";
|
|
2
|
+
export declare const AP2_ADAPTER_VERSION = "0.1";
|
|
3
|
+
export declare const AP2_PAYMENT_MANDATE_VCT = "mandate.payment.1";
|
|
4
|
+
/** AP2 `types/merchant.json`. */
|
|
5
|
+
export interface Ap2Merchant {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
website?: string;
|
|
9
|
+
}
|
|
10
|
+
/** AP2 `types/amount.json`: integer minor units of an ISO 4217 currency. */
|
|
11
|
+
export interface Ap2Amount {
|
|
12
|
+
amount: number;
|
|
13
|
+
currency: string;
|
|
14
|
+
}
|
|
15
|
+
/** A closed AP2 Payment Mandate (`payment_mandate.json`), as a verifier holds it. */
|
|
16
|
+
export interface Ap2PaymentMandate {
|
|
17
|
+
vct: string;
|
|
18
|
+
transaction_id: string;
|
|
19
|
+
payee: Ap2Merchant;
|
|
20
|
+
payment_amount: Ap2Amount;
|
|
21
|
+
payment_instrument: {
|
|
22
|
+
id: string;
|
|
23
|
+
type: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
};
|
|
26
|
+
pisp?: Record<string, unknown>;
|
|
27
|
+
execution_date?: string;
|
|
28
|
+
risk_data?: Record<string, unknown>;
|
|
29
|
+
iat?: number;
|
|
30
|
+
exp?: number;
|
|
31
|
+
}
|
|
32
|
+
/** Open Payment Mandate content, as the gateway projects it for you to sign. */
|
|
33
|
+
export interface Ap2OpenPaymentMandate {
|
|
34
|
+
vct: "mandate.payment.open.1";
|
|
35
|
+
constraints: Array<Record<string, unknown>>;
|
|
36
|
+
cnf: Record<string, unknown>;
|
|
37
|
+
payee: Ap2Merchant;
|
|
38
|
+
payment_amount: Ap2Amount;
|
|
39
|
+
iat: number;
|
|
40
|
+
exp: number;
|
|
41
|
+
}
|
|
42
|
+
/** What `decisions.projectAp2` returns. */
|
|
43
|
+
export interface Ap2Projection {
|
|
44
|
+
/** The claims your AP2 Trusted Surface or Trusted Agent Provider signs. */
|
|
45
|
+
mandate_content: Ap2OpenPaymentMandate;
|
|
46
|
+
/** `sha256:` digest of `mandate_content`; the artifact's executor reference is `ap2:<digest>`. */
|
|
47
|
+
content_digest: string;
|
|
48
|
+
/** The artifact this projection claimed. Report the AP2 outcome against it. */
|
|
49
|
+
authorisation_artifact_id: string;
|
|
50
|
+
/** Where the content came from. Not part of the AP2 claims. */
|
|
51
|
+
source: {
|
|
52
|
+
adapter: "AP2";
|
|
53
|
+
adapter_version: string;
|
|
54
|
+
target: Record<string, string>;
|
|
55
|
+
decision_id: string;
|
|
56
|
+
mandate_id: string;
|
|
57
|
+
mandate_version: number;
|
|
58
|
+
policy_hash: string;
|
|
59
|
+
/** The receipt that records this projection, in the decision's chain. */
|
|
60
|
+
authority_record: {
|
|
61
|
+
receipt_id: string;
|
|
62
|
+
action_hash: string;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export interface Ap2PaymentCheck {
|
|
67
|
+
/** The record verifies, it authorised this payment, and every field matched. */
|
|
68
|
+
valid: boolean;
|
|
69
|
+
record: AuthorityRecordVerification;
|
|
70
|
+
/** Each way the payment differs from what the record authorised. Empty when valid. */
|
|
71
|
+
mismatches: string[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The fields to put on `decisions.authorize` before an AP2 payment, so the
|
|
75
|
+
* mnd8t decision and the AP2 mandates describe one payment: the merchant id
|
|
76
|
+
* as the counterparty, and the open Checkout Mandate digest (the value AP2's
|
|
77
|
+
* `payment.reference` carries) as `external_reference`. Spread it into the
|
|
78
|
+
* rest of the request (agent, purpose, valuation and so on).
|
|
79
|
+
*/
|
|
80
|
+
export declare function ap2DecisionRequest(input: {
|
|
81
|
+
checkoutReference: string;
|
|
82
|
+
payee: Pick<Ap2Merchant, "id">;
|
|
83
|
+
amount: Ap2Amount;
|
|
84
|
+
}): Pick<AuthorizeRequest, "action_type" | "amount" | "counterparty_external_id" | "external_reference">;
|
|
85
|
+
/**
|
|
86
|
+
* For a credential provider, merchant or executor holding an AP2 payment and
|
|
87
|
+
* the Authority Record it claims: do they describe the same payment, and did
|
|
88
|
+
* the record authorise it?
|
|
89
|
+
*
|
|
90
|
+
* Run AP2's own checks first (signatures, key binding, constraints). This
|
|
91
|
+
* adds the mnd8t side: the record's signature and integrity, an enforced and
|
|
92
|
+
* authorised decision that was not revoked, and payee, currency, amount and
|
|
93
|
+
* checkout reference field by field. v0.1 binds immediate payments only.
|
|
94
|
+
*
|
|
95
|
+
* A valid result proves what mnd8t decided when the record was signed. It
|
|
96
|
+
* does not say the authority still stands; `receipts.verifyPresented`
|
|
97
|
+
* reports that, to the record's own organisation.
|
|
98
|
+
*/
|
|
99
|
+
export declare function verifyAp2PaymentAgainstRecord(input: {
|
|
100
|
+
openMandate: Record<string, unknown>;
|
|
101
|
+
closedMandate: Ap2PaymentMandate;
|
|
102
|
+
record: Record<string, unknown>;
|
|
103
|
+
keys: readonly VerificationKey[];
|
|
104
|
+
}): Promise<Ap2PaymentCheck>;
|
package/dist/ap2.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AP2 helpers, dependency-free. Mirrors the gateway's AP2 adapter v0.1
|
|
3
|
+
* (`@mandate/authority-adapters`) exactly; a contract test in the gateway
|
|
4
|
+
* runs both against the same records.
|
|
5
|
+
*
|
|
6
|
+
* Written against AP2 v0.2.0. This is a versioned mapping, not certified AP2
|
|
7
|
+
* conformance.
|
|
8
|
+
*/
|
|
9
|
+
import { verifyAuthorityRecord } from "./record.js";
|
|
10
|
+
export const AP2_ADAPTER_VERSION = "0.1";
|
|
11
|
+
export const AP2_PAYMENT_MANDATE_VCT = "mandate.payment.1";
|
|
12
|
+
/**
|
|
13
|
+
* The fields to put on `decisions.authorize` before an AP2 payment, so the
|
|
14
|
+
* mnd8t decision and the AP2 mandates describe one payment: the merchant id
|
|
15
|
+
* as the counterparty, and the open Checkout Mandate digest (the value AP2's
|
|
16
|
+
* `payment.reference` carries) as `external_reference`. Spread it into the
|
|
17
|
+
* rest of the request (agent, purpose, valuation and so on).
|
|
18
|
+
*/
|
|
19
|
+
export function ap2DecisionRequest(input) {
|
|
20
|
+
return {
|
|
21
|
+
action_type: "PAYMENT",
|
|
22
|
+
amount: { asset: input.amount.currency, asset_amount_minor: input.amount.amount },
|
|
23
|
+
counterparty_external_id: input.payee.id,
|
|
24
|
+
external_reference: input.checkoutReference,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function asRecord(value) {
|
|
28
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
29
|
+
}
|
|
30
|
+
function checkoutReferenceOf(openMandate) {
|
|
31
|
+
const constraints = Array.isArray(openMandate["constraints"]) ? openMandate["constraints"] : [];
|
|
32
|
+
const ref = constraints.map(asRecord).find((c) => c["type"] === "payment.reference");
|
|
33
|
+
const id = ref?.["conditional_transaction_id"];
|
|
34
|
+
return typeof id === "string" ? id : null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* For a credential provider, merchant or executor holding an AP2 payment and
|
|
38
|
+
* the Authority Record it claims: do they describe the same payment, and did
|
|
39
|
+
* the record authorise it?
|
|
40
|
+
*
|
|
41
|
+
* Run AP2's own checks first (signatures, key binding, constraints). This
|
|
42
|
+
* adds the mnd8t side: the record's signature and integrity, an enforced and
|
|
43
|
+
* authorised decision that was not revoked, and payee, currency, amount and
|
|
44
|
+
* checkout reference field by field. v0.1 binds immediate payments only.
|
|
45
|
+
*
|
|
46
|
+
* A valid result proves what mnd8t decided when the record was signed. It
|
|
47
|
+
* does not say the authority still stands; `receipts.verifyPresented`
|
|
48
|
+
* reports that, to the record's own organisation.
|
|
49
|
+
*/
|
|
50
|
+
export async function verifyAp2PaymentAgainstRecord(input) {
|
|
51
|
+
const { closedMandate: closed } = input;
|
|
52
|
+
const record = await verifyAuthorityRecord(input.record, input.keys);
|
|
53
|
+
const mismatches = [];
|
|
54
|
+
if (!record.valid)
|
|
55
|
+
mismatches.push(`authority record does not verify: ${record.reason ?? "invalid"}`);
|
|
56
|
+
const decision = asRecord(input.record["decision"]);
|
|
57
|
+
const approval = asRecord(input.record["approval"]);
|
|
58
|
+
const intent = asRecord(input.record["intent"]);
|
|
59
|
+
if (decision["mode"] !== "ENFORCE")
|
|
60
|
+
mismatches.push("the record is a shadow-mode decision and authorises nothing");
|
|
61
|
+
const authorised = decision["status"] === "APPROVE" || (decision["status"] === "ESCALATE" && approval["status"] === "APPROVED");
|
|
62
|
+
if (!authorised)
|
|
63
|
+
mismatches.push(`the record does not authorise a payment (decision ${String(decision["status"])})`);
|
|
64
|
+
if (input.record["revocation"] != null)
|
|
65
|
+
mismatches.push("the record shows the authority was revoked");
|
|
66
|
+
if (closed.vct !== AP2_PAYMENT_MANDATE_VCT)
|
|
67
|
+
mismatches.push(`unsupported payment mandate vct ${String(closed.vct)}`);
|
|
68
|
+
if (intent["action_type"] !== "PAYMENT")
|
|
69
|
+
mismatches.push("the record is not for a PAYMENT");
|
|
70
|
+
if (intent["asset"] !== closed.payment_amount?.currency)
|
|
71
|
+
mismatches.push("currency differs from the authorised asset");
|
|
72
|
+
if (intent["amount_minor"] !== closed.payment_amount?.amount)
|
|
73
|
+
mismatches.push("amount differs from the authorised amount");
|
|
74
|
+
if (intent["counterparty"] !== closed.payee?.id)
|
|
75
|
+
mismatches.push("payee differs from the authorised counterparty");
|
|
76
|
+
const checkoutReference = checkoutReferenceOf(input.openMandate);
|
|
77
|
+
if (checkoutReference === null) {
|
|
78
|
+
mismatches.push("the open Payment Mandate has no payment.reference constraint");
|
|
79
|
+
}
|
|
80
|
+
else if (intent["external_reference"] !== checkoutReference) {
|
|
81
|
+
mismatches.push("checkout reference differs from the authorised external_reference");
|
|
82
|
+
}
|
|
83
|
+
if (closed.execution_date !== undefined) {
|
|
84
|
+
mismatches.push("adapter v0.1 binds immediate payments only; this payment carries an execution_date");
|
|
85
|
+
}
|
|
86
|
+
return { valid: mismatches.length === 0, record, mismatches };
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=ap2.js.map
|
package/dist/ap2.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ap2.js","sourceRoot":"","sources":["../src/ap2.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { Agent, AuthorizeRequest, AuthorizeResponse, ConfirmRequest, Counterparty, CounterpartyAuthorityStatus, CreateAgentRequest, CreateCounterpartyRequest, CreateMandateRequest, EvidenceReceiptEnvelope, Mandate, PublishMandateOptions, PublishResult } from "./types.js";
|
|
1
|
+
import type { Agent, AssertValuationRequest, AuthorizeRequest, AuthorizeResponse, ConfirmRequest, Counterparty, CounterpartyAuthorityStatus, CreateAgentRequest, CreateCounterpartyRequest, CreateMandateRequest, EvidenceReceiptEnvelope, Mandate, PublishMandateOptions, PublishResult, ActionFields, AuthorityRecordVerification, PresentedRecordVerification, Valuation, VerificationKey } from "./types.js";
|
|
2
|
+
import type { Ap2Projection } from "./ap2.js";
|
|
2
3
|
export interface MandateClientOptions {
|
|
3
4
|
apiKey: string;
|
|
4
5
|
/** Your workspace URL. Defaults to http://localhost:4000, what `pnpm dev` serves. */
|
|
@@ -61,6 +62,15 @@ export declare class MandateClient {
|
|
|
61
62
|
data: Mandate[];
|
|
62
63
|
}>;
|
|
63
64
|
};
|
|
65
|
+
/**
|
|
66
|
+
* Asserting what an action is worth. Requires the `valuations:assert`
|
|
67
|
+
* scope, which the AGENT preset does not carry: call this from the backend
|
|
68
|
+
* that knows the rate, then hand the id to the agent.
|
|
69
|
+
*/
|
|
70
|
+
readonly valuations: {
|
|
71
|
+
assert: (body: AssertValuationRequest) => Promise<Valuation>;
|
|
72
|
+
get: (id: string) => Promise<Record<string, unknown>>;
|
|
73
|
+
};
|
|
64
74
|
readonly decisions: {
|
|
65
75
|
/**
|
|
66
76
|
* Submits a proposed financial action. Generates an idempotency key
|
|
@@ -71,6 +81,18 @@ export declare class MandateClient {
|
|
|
71
81
|
confirm: (intentId: string, body: ConfirmRequest) => Promise<Record<string, unknown>>;
|
|
72
82
|
cancel: (intentId: string, reason?: string) => Promise<Record<string, unknown>>;
|
|
73
83
|
get: (intentId: string) => Promise<Record<string, unknown>>;
|
|
84
|
+
/**
|
|
85
|
+
* Spends an approved decision as AP2 v0.2 Open Payment Mandate content,
|
|
86
|
+
* for your AP2 Trusted Surface or Trusted Agent Provider to sign
|
|
87
|
+
* (deployment flag ENABLE_AP2_MAPPING). This claims the decision's
|
|
88
|
+
* authorisation artifact, so it succeeds once per decision and is never
|
|
89
|
+
* retried automatically. Report the outcome with `decisions.confirm`
|
|
90
|
+
* or `artifacts.fail`, using the returned `authorisation_artifact_id`.
|
|
91
|
+
*/
|
|
92
|
+
projectAp2: (intentId: string, body: {
|
|
93
|
+
cnf: Record<string, unknown>;
|
|
94
|
+
ttl_seconds?: number;
|
|
95
|
+
}) => Promise<Ap2Projection>;
|
|
74
96
|
list: (params?: {
|
|
75
97
|
status?: string;
|
|
76
98
|
decision?: string;
|
|
@@ -102,21 +124,29 @@ export declare class MandateClient {
|
|
|
102
124
|
};
|
|
103
125
|
readonly receipts: {
|
|
104
126
|
get: (receiptId: string) => Promise<EvidenceReceiptEnvelope>;
|
|
105
|
-
/** Server-side verification. */
|
|
127
|
+
/** Server-side verification of a stored receipt, by id. */
|
|
106
128
|
verifyRemote: (receiptId: string) => Promise<{
|
|
107
129
|
valid: boolean;
|
|
108
130
|
reason: string | null;
|
|
109
131
|
}>;
|
|
110
132
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
133
|
+
* Server-side verification of a record you hold (someone else's
|
|
134
|
+
* included), optionally against the action you are about to execute.
|
|
135
|
+
* Also reports the mandate's current state, separately, when the record
|
|
136
|
+
* belongs to your organisation.
|
|
137
|
+
*/
|
|
138
|
+
verifyPresented: (receipt: Record<string, unknown>, expectedAction?: Partial<ActionFields>) => Promise<PresentedRecordVerification>;
|
|
139
|
+
/** The published verification keys, retired ones included. */
|
|
140
|
+
keys: () => Promise<VerificationKey[]>;
|
|
141
|
+
/**
|
|
142
|
+
* Independent local verification: checks the Ed25519 signature against
|
|
143
|
+
* the key the record names (from the gateway's well-known document, or a
|
|
144
|
+
* pinned PEM), that its action_hash binds the action it records, and,
|
|
145
|
+
* with `expectedAction`, that it is the action you hold.
|
|
114
146
|
*/
|
|
115
147
|
verify: (receipt: Record<string, unknown>, opts?: {
|
|
116
148
|
publicKeyPem?: string;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
reason: string | null;
|
|
120
|
-
}>;
|
|
149
|
+
expectedAction?: Partial<ActionFields>;
|
|
150
|
+
}) => Promise<AuthorityRecordVerification>;
|
|
121
151
|
};
|
|
122
152
|
}
|
package/dist/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { errorFromResponse, MandateError } from "./errors.js";
|
|
2
|
-
import {
|
|
2
|
+
import { verifyAuthorityRecord } from "./record.js";
|
|
3
3
|
function randomIdempotencyKey() {
|
|
4
4
|
const bytes = new Uint8Array(16);
|
|
5
5
|
crypto.getRandomValues(bytes);
|
|
@@ -96,6 +96,15 @@ export class MandateClient {
|
|
|
96
96
|
get: (id) => this.request("GET", `/v1/mandates/${id}`),
|
|
97
97
|
list: () => this.request("GET", "/v1/mandates"),
|
|
98
98
|
};
|
|
99
|
+
/**
|
|
100
|
+
* Asserting what an action is worth. Requires the `valuations:assert`
|
|
101
|
+
* scope, which the AGENT preset does not carry: call this from the backend
|
|
102
|
+
* that knows the rate, then hand the id to the agent.
|
|
103
|
+
*/
|
|
104
|
+
valuations = {
|
|
105
|
+
assert: (body) => this.request("POST", "/v1/valuations", { body }),
|
|
106
|
+
get: (id) => this.request("GET", `/v1/valuations/${encodeURIComponent(id)}`),
|
|
107
|
+
};
|
|
99
108
|
decisions = {
|
|
100
109
|
/**
|
|
101
110
|
* Submits a proposed financial action. Generates an idempotency key
|
|
@@ -113,6 +122,15 @@ export class MandateClient {
|
|
|
113
122
|
confirm: (intentId, body) => this.request("POST", `/v1/decision-intents/${intentId}/confirm`, { body }),
|
|
114
123
|
cancel: (intentId, reason) => this.request("POST", `/v1/decision-intents/${intentId}/cancel`, { body: { reason } }),
|
|
115
124
|
get: (intentId) => this.request("GET", `/v1/decision-intents/${intentId}`),
|
|
125
|
+
/**
|
|
126
|
+
* Spends an approved decision as AP2 v0.2 Open Payment Mandate content,
|
|
127
|
+
* for your AP2 Trusted Surface or Trusted Agent Provider to sign
|
|
128
|
+
* (deployment flag ENABLE_AP2_MAPPING). This claims the decision's
|
|
129
|
+
* authorisation artifact, so it succeeds once per decision and is never
|
|
130
|
+
* retried automatically. Report the outcome with `decisions.confirm`
|
|
131
|
+
* or `artifacts.fail`, using the returned `authorisation_artifact_id`.
|
|
132
|
+
*/
|
|
133
|
+
projectAp2: (intentId, body) => this.request("POST", `/v1/decision-intents/${intentId}/ap2-open-payment-mandate`, { body }),
|
|
116
134
|
list: (params = {}) => {
|
|
117
135
|
const qs = new URLSearchParams(Object.entries(params).filter(([, v]) => v !== undefined)).toString();
|
|
118
136
|
return this.request("GET", `/v1/decision-intents${qs ? `?${qs}` : ""}`);
|
|
@@ -134,24 +152,42 @@ export class MandateClient {
|
|
|
134
152
|
};
|
|
135
153
|
receipts = {
|
|
136
154
|
get: (receiptId) => this.request("GET", `/v1/evidence-receipts/${receiptId}`),
|
|
137
|
-
/** Server-side verification. */
|
|
155
|
+
/** Server-side verification of a stored receipt, by id. */
|
|
138
156
|
verifyRemote: (receiptId) => this.request("GET", `/v1/evidence-receipts/${receiptId}/verify`),
|
|
139
157
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
158
|
+
* Server-side verification of a record you hold (someone else's
|
|
159
|
+
* included), optionally against the action you are about to execute.
|
|
160
|
+
* Also reports the mandate's current state, separately, when the record
|
|
161
|
+
* belongs to your organisation.
|
|
162
|
+
*/
|
|
163
|
+
verifyPresented: (receipt, expectedAction) => this.request("POST", "/v1/evidence-receipts/verify", {
|
|
164
|
+
body: { receipt, ...(expectedAction ? { expected_action: expectedAction } : {}) },
|
|
165
|
+
retryable: true,
|
|
166
|
+
}),
|
|
167
|
+
/** The published verification keys, retired ones included. */
|
|
168
|
+
keys: async () => {
|
|
169
|
+
const res = await this.fetchImpl(`${this.baseUrl}/.well-known/mandate-keys.json`);
|
|
170
|
+
if (!res.ok)
|
|
171
|
+
throw new MandateError(res.status, "KEYS_UNAVAILABLE", `Could not fetch verification keys (HTTP ${res.status})`);
|
|
172
|
+
return (await res.json()).keys;
|
|
173
|
+
},
|
|
174
|
+
/**
|
|
175
|
+
* Independent local verification: checks the Ed25519 signature against
|
|
176
|
+
* the key the record names (from the gateway's well-known document, or a
|
|
177
|
+
* pinned PEM), that its action_hash binds the action it records, and,
|
|
178
|
+
* with `expectedAction`, that it is the action you hold.
|
|
143
179
|
*/
|
|
144
180
|
verify: async (receipt, opts = {}) => {
|
|
145
|
-
let
|
|
146
|
-
if (
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
181
|
+
let keys;
|
|
182
|
+
if (opts.publicKeyPem) {
|
|
183
|
+
// A pinned key verifies whatever key_id the record names.
|
|
184
|
+
const keyId = receipt.signature?.key_id ?? "pinned";
|
|
185
|
+
keys = [{ key_id: keyId, public_key_pem: opts.publicKeyPem }];
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
keys = await this.receipts.keys();
|
|
151
189
|
}
|
|
152
|
-
|
|
153
|
-
return { valid: false, reason: "no verification key available" };
|
|
154
|
-
return verifyReceiptSignature(receipt, pem);
|
|
190
|
+
return verifyAuthorityRecord(receipt, keys, { expectedAction: opts.expectedAction });
|
|
155
191
|
},
|
|
156
192
|
};
|
|
157
193
|
}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { MandateClient, type MandateClientOptions } from "./client.js";
|
|
2
2
|
export { verifyReceiptSignature } from "./verify.js";
|
|
3
|
+
export { ACTION_DIGEST_VERSION, actionDigest, canonicalAction, verifyAuthorityRecord } from "./record.js";
|
|
4
|
+
export { AP2_ADAPTER_VERSION, AP2_PAYMENT_MANDATE_VCT, ap2DecisionRequest, verifyAp2PaymentAgainstRecord, type Ap2Amount, type Ap2Merchant, type Ap2OpenPaymentMandate, type Ap2Projection, type Ap2PaymentCheck, type Ap2PaymentMandate, } from "./ap2.js";
|
|
3
5
|
export * from "./types.js";
|
|
4
6
|
export * from "./errors.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { MandateClient } from "./client.js";
|
|
2
2
|
export { verifyReceiptSignature } from "./verify.js";
|
|
3
|
+
export { ACTION_DIGEST_VERSION, actionDigest, canonicalAction, verifyAuthorityRecord } from "./record.js";
|
|
4
|
+
export { AP2_ADAPTER_VERSION, AP2_PAYMENT_MANDATE_VCT, ap2DecisionRequest, verifyAp2PaymentAgainstRecord, } from "./ap2.js";
|
|
3
5
|
export * from "./types.js";
|
|
4
6
|
export * from "./errors.js";
|
|
5
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA6B,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA6B,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC1G,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,6BAA6B,GAO9B,MAAM,UAAU,CAAC;AAClB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
|
package/dist/record.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ActionFields, AuthorityRecordVerification, VerificationKey } from "./types.js";
|
|
2
|
+
export declare const ACTION_DIGEST_VERSION = "1";
|
|
3
|
+
/**
|
|
4
|
+
* The canonical action object: the fixed key set plus `digest_version`.
|
|
5
|
+
* Absent optional fields are null. Values are used exactly as given: no
|
|
6
|
+
* trimming, case folding or Unicode normalisation.
|
|
7
|
+
*/
|
|
8
|
+
export declare function canonicalAction(fields: Readonly<Record<string, unknown>>): Record<string, unknown>;
|
|
9
|
+
/**
|
|
10
|
+
* `sha256:<hex>` of the canonical action: the value an Authority Record
|
|
11
|
+
* carries as `action_hash`. Compute it from the instruction you are about to
|
|
12
|
+
* execute and compare.
|
|
13
|
+
*/
|
|
14
|
+
export declare function actionDigest(fields: Partial<ActionFields> | Readonly<Record<string, unknown>>): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Verifies an Authority Record locally: the signature against the published
|
|
17
|
+
* key the record names, that its `action_hash` binds the action it records,
|
|
18
|
+
* and, if you pass `expectedAction`, that it is the action you hold.
|
|
19
|
+
*
|
|
20
|
+
* A valid record proves what mnd8t decided then. It does not say the agent
|
|
21
|
+
* is authorised now.
|
|
22
|
+
*/
|
|
23
|
+
export declare function verifyAuthorityRecord(receipt: Record<string, unknown>, keys: readonly VerificationKey[], options?: {
|
|
24
|
+
expectedAction?: Partial<ActionFields>;
|
|
25
|
+
}): Promise<AuthorityRecordVerification>;
|
package/dist/record.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authority Record verification, dependency-free (WebCrypto). Mirrors the
|
|
3
|
+
* gateway's `@mandate/evidence` record checks exactly, and is tested against
|
|
4
|
+
* the same action-digest vectors.
|
|
5
|
+
*/
|
|
6
|
+
import { canonicalJson, verifyReceiptSignature } from "./verify.js";
|
|
7
|
+
export const ACTION_DIGEST_VERSION = "1";
|
|
8
|
+
const OPTIONAL_KEYS = ["financial_account_id", "counterparty", "destination", "purpose", "external_reference"];
|
|
9
|
+
/**
|
|
10
|
+
* The canonical action object: the fixed key set plus `digest_version`.
|
|
11
|
+
* Absent optional fields are null. Values are used exactly as given: no
|
|
12
|
+
* trimming, case folding or Unicode normalisation.
|
|
13
|
+
*/
|
|
14
|
+
export function canonicalAction(fields) {
|
|
15
|
+
const amount = fields["amount_minor"];
|
|
16
|
+
if (typeof amount !== "number" || !Number.isSafeInteger(amount) || amount < 0) {
|
|
17
|
+
throw new Error("action digest: amount_minor must be a non-negative safe integer");
|
|
18
|
+
}
|
|
19
|
+
const out = { digest_version: ACTION_DIGEST_VERSION, amount_minor: amount };
|
|
20
|
+
for (const key of ["action_type", "asset"]) {
|
|
21
|
+
const value = fields[key];
|
|
22
|
+
if (typeof value !== "string" || value.length === 0)
|
|
23
|
+
throw new Error(`action digest: ${key} is required`);
|
|
24
|
+
out[key] = value;
|
|
25
|
+
}
|
|
26
|
+
for (const key of OPTIONAL_KEYS) {
|
|
27
|
+
const value = fields[key];
|
|
28
|
+
if (value !== undefined && value !== null && typeof value !== "string") {
|
|
29
|
+
throw new Error(`action digest: ${key} must be a string or null`);
|
|
30
|
+
}
|
|
31
|
+
out[key] = value ?? null;
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* `sha256:<hex>` of the canonical action: the value an Authority Record
|
|
37
|
+
* carries as `action_hash`. Compute it from the instruction you are about to
|
|
38
|
+
* execute and compare.
|
|
39
|
+
*/
|
|
40
|
+
export async function actionDigest(fields) {
|
|
41
|
+
const bytes = new TextEncoder().encode(canonicalJson(canonicalAction(fields)));
|
|
42
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
|
|
43
|
+
return `sha256:${Array.from(digest, (b) => b.toString(16).padStart(2, "0")).join("")}`;
|
|
44
|
+
}
|
|
45
|
+
function recordedAction(receipt) {
|
|
46
|
+
const intent = (receipt["intent"] ?? {});
|
|
47
|
+
const out = {};
|
|
48
|
+
for (const key of ["action_type", "asset", "amount_minor", ...OPTIONAL_KEYS])
|
|
49
|
+
out[key] = intent[key];
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
async function digestOrNull(fields) {
|
|
53
|
+
try {
|
|
54
|
+
return await actionDigest(fields);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Verifies an Authority Record locally: the signature against the published
|
|
62
|
+
* key the record names, that its `action_hash` binds the action it records,
|
|
63
|
+
* and, if you pass `expectedAction`, that it is the action you hold.
|
|
64
|
+
*
|
|
65
|
+
* A valid record proves what mnd8t decided then. It does not say the agent
|
|
66
|
+
* is authorised now.
|
|
67
|
+
*/
|
|
68
|
+
export async function verifyAuthorityRecord(receipt, keys, options = {}) {
|
|
69
|
+
const signature = receipt["signature"];
|
|
70
|
+
const keyId = typeof signature?.key_id === "string" ? signature.key_id : null;
|
|
71
|
+
const recordedHash = typeof receipt["action_hash"] === "string" ? receipt["action_hash"] : null;
|
|
72
|
+
const result = {
|
|
73
|
+
valid: false,
|
|
74
|
+
signature_valid: false,
|
|
75
|
+
record_integrity: null,
|
|
76
|
+
action_match: null,
|
|
77
|
+
key_id: keyId,
|
|
78
|
+
key_status: null,
|
|
79
|
+
action_hash: recordedHash,
|
|
80
|
+
reason: null,
|
|
81
|
+
};
|
|
82
|
+
const key = keyId ? keys.find((k) => k.key_id === keyId) : undefined;
|
|
83
|
+
if (!key) {
|
|
84
|
+
result.reason = keyId ? `unknown key_id ${keyId}` : "receipt has no signature";
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
result.key_status = key.status ?? null;
|
|
88
|
+
const sig = await verifyReceiptSignature(receipt, key.public_key_pem);
|
|
89
|
+
result.signature_valid = sig.valid;
|
|
90
|
+
if (!sig.valid) {
|
|
91
|
+
result.reason = sig.reason;
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
if (recordedHash !== null) {
|
|
95
|
+
result.record_integrity = (await digestOrNull(recordedAction(receipt))) === recordedHash;
|
|
96
|
+
if (!result.record_integrity)
|
|
97
|
+
result.reason = "action_hash does not match the recorded action";
|
|
98
|
+
}
|
|
99
|
+
else if ("action_hash" in receipt) {
|
|
100
|
+
result.record_integrity = false;
|
|
101
|
+
result.reason = "action_hash is not a string";
|
|
102
|
+
}
|
|
103
|
+
if (options.expectedAction) {
|
|
104
|
+
if (recordedHash === null) {
|
|
105
|
+
result.action_match = false;
|
|
106
|
+
result.reason ??= "record has no action_hash to compare against";
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
result.action_match = (await digestOrNull(options.expectedAction)) === recordedHash;
|
|
110
|
+
if (!result.action_match)
|
|
111
|
+
result.reason ??= "expected action does not match the recorded action_hash";
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
result.valid = result.signature_valid && result.record_integrity !== false && result.action_match !== false;
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.js","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -46,9 +46,48 @@ export interface MandatePolicy {
|
|
|
46
46
|
start: string;
|
|
47
47
|
end: string;
|
|
48
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* What this mandate requires of an external identity / session attestation
|
|
51
|
+
* presented with each request. Can only refuse; never widens authority.
|
|
52
|
+
*/
|
|
53
|
+
identity_attestation?: {
|
|
54
|
+
required?: boolean;
|
|
55
|
+
protocols?: IdentityAttestationProtocol[];
|
|
56
|
+
trusted_issuers?: string[];
|
|
57
|
+
bind_agent?: boolean;
|
|
58
|
+
};
|
|
49
59
|
effective_at: string;
|
|
50
60
|
expires_at: string;
|
|
51
61
|
}
|
|
62
|
+
/** Identity and session protocols mnd8t models as attestation sources. */
|
|
63
|
+
export type IdentityAttestationProtocol = "AFSP" | "OTHER";
|
|
64
|
+
/**
|
|
65
|
+
* An external identity / session attestation: who the agent is and which
|
|
66
|
+
* session was cleared. Issued by an admission layer such as AFSP, not by
|
|
67
|
+
* mnd8t. Field names follow the AFSP v0.1 session token where it defines
|
|
68
|
+
* one. Recorded in the Authority Record beside the mandate; not verified by
|
|
69
|
+
* mnd8t.
|
|
70
|
+
*/
|
|
71
|
+
export interface IdentityAttestation {
|
|
72
|
+
protocol: IdentityAttestationProtocol;
|
|
73
|
+
protocol_version: string;
|
|
74
|
+
issuer: string;
|
|
75
|
+
clearing_institution?: string;
|
|
76
|
+
agent_id: string;
|
|
77
|
+
/** Optional: AFSP tokens carry no principal identifier. */
|
|
78
|
+
principal_id?: string;
|
|
79
|
+
session_id: string;
|
|
80
|
+
package_id?: string;
|
|
81
|
+
/** AFSP: PROCEED_TO_KYC, REQUEST_ADDITIONAL_VERIFICATION or DECLINE_SESSION. */
|
|
82
|
+
clearance_decision?: string;
|
|
83
|
+
/** AFSP: READ, DISCOVER, PRESENT, INITIATE, EXECUTE. */
|
|
84
|
+
action_classes?: string[];
|
|
85
|
+
not_before?: string;
|
|
86
|
+
not_after: string;
|
|
87
|
+
single_use?: boolean;
|
|
88
|
+
/** `sha256:<hex>` of the raw attestation token; the token itself is never sent. */
|
|
89
|
+
token_digest?: string;
|
|
90
|
+
}
|
|
52
91
|
export interface CreateMandateRequest {
|
|
53
92
|
agent_id: string;
|
|
54
93
|
name: string;
|
|
@@ -165,6 +204,8 @@ export interface AuthorizeRequest {
|
|
|
165
204
|
counterparty_country?: string;
|
|
166
205
|
customer_classification?: string;
|
|
167
206
|
};
|
|
207
|
+
/** External identity / session attestation (AFSP or another protocol). */
|
|
208
|
+
identity_attestation?: IdentityAttestation;
|
|
168
209
|
/** Deprecated: prefer `amount.asset_amount_minor`. */
|
|
169
210
|
amount_minor?: number;
|
|
170
211
|
policy_amount_minor?: number;
|
|
@@ -181,9 +222,35 @@ export interface AuthorizeRequest {
|
|
|
181
222
|
purpose?: string;
|
|
182
223
|
occurred_at?: string;
|
|
183
224
|
metadata?: Record<string, unknown>;
|
|
225
|
+
/**
|
|
226
|
+
* Reference to a valuation asserted by a credential holding
|
|
227
|
+
* `valuations:assert`. Takes precedence over an inline `valuation`, and is
|
|
228
|
+
* required by mandates with `require_asserted_valuation` — an agent key
|
|
229
|
+
* cannot mint one, which is the point.
|
|
230
|
+
*/
|
|
231
|
+
valuation_id?: string;
|
|
184
232
|
/** Overrides the automatically generated idempotency key. */
|
|
185
233
|
idempotencyKey?: string;
|
|
186
234
|
}
|
|
235
|
+
export interface AssertValuationRequest {
|
|
236
|
+
asset: string;
|
|
237
|
+
asset_amount_minor: number;
|
|
238
|
+
policy_amount_minor: number;
|
|
239
|
+
policy_currency: string;
|
|
240
|
+
source?: string;
|
|
241
|
+
rate_reference?: string;
|
|
242
|
+
valued_at?: string;
|
|
243
|
+
/** 30–3600, default 300. */
|
|
244
|
+
ttl_seconds?: number;
|
|
245
|
+
}
|
|
246
|
+
export interface Valuation {
|
|
247
|
+
id: string;
|
|
248
|
+
asset: string;
|
|
249
|
+
asset_amount_minor: number;
|
|
250
|
+
policy_amount_minor: number;
|
|
251
|
+
policy_currency: string;
|
|
252
|
+
expires_at: string;
|
|
253
|
+
}
|
|
187
254
|
export interface AuthorizeResponse {
|
|
188
255
|
id: string;
|
|
189
256
|
mode: "SHADOW" | "ENFORCE";
|
|
@@ -201,6 +268,85 @@ export interface AuthorizeResponse {
|
|
|
201
268
|
} | null;
|
|
202
269
|
authorisation_artifact: AuthorisationArtifactSummary | null;
|
|
203
270
|
evidence_receipt_id: string | null;
|
|
271
|
+
/** The signed Authority Record this decision produced (gateway ≥ receipt 1.1). */
|
|
272
|
+
authority_record?: AuthorityRecordSummary;
|
|
273
|
+
}
|
|
274
|
+
export interface AuthorityRecordSummary {
|
|
275
|
+
receipt_id: string;
|
|
276
|
+
receipt_version: string;
|
|
277
|
+
/** `sha256:` digest of the proposed action; see `actionDigest`. */
|
|
278
|
+
action_hash: string;
|
|
279
|
+
key_id: string;
|
|
280
|
+
/** GET: the signed record. */
|
|
281
|
+
url: string;
|
|
282
|
+
/** POST { receipt, expected_action? }: verify a presented record. */
|
|
283
|
+
verify_url: string;
|
|
284
|
+
}
|
|
285
|
+
/** The fields an Authority Record's `action_hash` is computed over. */
|
|
286
|
+
export interface ActionFields {
|
|
287
|
+
action_type: string;
|
|
288
|
+
financial_account_id: string | null;
|
|
289
|
+
asset: string;
|
|
290
|
+
/** Integer minor units of the asset that moves. */
|
|
291
|
+
amount_minor: number;
|
|
292
|
+
counterparty: string | null;
|
|
293
|
+
destination: string | null;
|
|
294
|
+
purpose: string | null;
|
|
295
|
+
external_reference: string | null;
|
|
296
|
+
}
|
|
297
|
+
/** A key from /.well-known/mandate-keys.json. */
|
|
298
|
+
export interface VerificationKey {
|
|
299
|
+
key_id: string;
|
|
300
|
+
public_key_pem: string;
|
|
301
|
+
/** Older gateways omit it. Retired keys verify; only the active key signs. */
|
|
302
|
+
status?: "ACTIVE" | "RETIRED";
|
|
303
|
+
}
|
|
304
|
+
export interface AuthorityRecordVerification {
|
|
305
|
+
/** signature_valid, and neither record_integrity nor action_match is false. */
|
|
306
|
+
valid: boolean;
|
|
307
|
+
signature_valid: boolean;
|
|
308
|
+
/** The recorded action_hash is the digest of the recorded action. Null on a
|
|
309
|
+
* 1.0 receipt, which predates action hashes. */
|
|
310
|
+
record_integrity: boolean | null;
|
|
311
|
+
/** Your expected action produces the recorded action_hash. Null if none given. */
|
|
312
|
+
action_match: boolean | null;
|
|
313
|
+
key_id: string | null;
|
|
314
|
+
key_status: "ACTIVE" | "RETIRED" | null;
|
|
315
|
+
action_hash: string | null;
|
|
316
|
+
reason: string | null;
|
|
317
|
+
}
|
|
318
|
+
export type CurrentAuthority = {
|
|
319
|
+
status: "NOT_CHECKED";
|
|
320
|
+
reason: "RECORD_NOT_VERIFIED" | "AUTHENTICATION_REQUIRED" | "NOT_PERMITTED" | "NO_MANDATE";
|
|
321
|
+
} | {
|
|
322
|
+
status: "CHECKED";
|
|
323
|
+
checked_at: string;
|
|
324
|
+
mandate_status: string;
|
|
325
|
+
current_version: number | null;
|
|
326
|
+
recorded_version_is_current: boolean;
|
|
327
|
+
expires_at: string | null;
|
|
328
|
+
expired: boolean;
|
|
329
|
+
revoked_at: string | null;
|
|
330
|
+
note: string;
|
|
331
|
+
};
|
|
332
|
+
/** Response of POST /v1/evidence-receipts/verify. */
|
|
333
|
+
export interface PresentedRecordVerification extends AuthorityRecordVerification {
|
|
334
|
+
receipt_id: string | null;
|
|
335
|
+
receipt_version: string | null;
|
|
336
|
+
decision: {
|
|
337
|
+
status: string;
|
|
338
|
+
effective_status: string;
|
|
339
|
+
mode: string;
|
|
340
|
+
reasons: string[];
|
|
341
|
+
decided_at: string;
|
|
342
|
+
} | null;
|
|
343
|
+
mandate_reference: {
|
|
344
|
+
id: string | null;
|
|
345
|
+
version: number | null;
|
|
346
|
+
policy_hash: string | null;
|
|
347
|
+
} | null;
|
|
348
|
+
/** The mandate now, reported apart from the record's validity. */
|
|
349
|
+
current_authority: CurrentAuthority;
|
|
204
350
|
}
|
|
205
351
|
export interface ConfirmRequest {
|
|
206
352
|
provider: string;
|
package/dist/verify.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* browsers via WebCrypto. Mirrors the gateway's canonicalisation exactly:
|
|
4
4
|
* sorted keys, no whitespace, integers only, undefined members dropped.
|
|
5
5
|
*/
|
|
6
|
+
export declare function canonicalJson(value: unknown): string;
|
|
6
7
|
export declare function verifyReceiptSignature(receipt: Record<string, unknown>, publicKeyPem: string): Promise<{
|
|
7
8
|
valid: boolean;
|
|
8
9
|
reason: string | null;
|
package/dist/verify.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* browsers via WebCrypto. Mirrors the gateway's canonicalisation exactly:
|
|
4
4
|
* sorted keys, no whitespace, integers only, undefined members dropped.
|
|
5
5
|
*/
|
|
6
|
-
function canonicalJson(value) {
|
|
6
|
+
export function canonicalJson(value) {
|
|
7
7
|
if (value === null)
|
|
8
8
|
return "null";
|
|
9
9
|
switch (typeof value) {
|
package/dist/verify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@mnd8t/sdk",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "TypeScript SDK for the Mandate Gateway authority API",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"ai-agents",
|
|
7
|
-
"authority",
|
|
8
|
-
"payments",
|
|
9
|
-
"policy",
|
|
10
|
-
"evidence",
|
|
11
|
-
"mnd8t"
|
|
12
|
-
],
|
|
13
|
-
"license": "MIT",
|
|
14
|
-
"homepage": "https://mnd8t.com/docs/sdk",
|
|
15
|
-
"author": "Glencorse Ltd",
|
|
16
|
-
"type": "module",
|
|
17
|
-
"engines": {
|
|
18
|
-
"node": ">=22"
|
|
19
|
-
},
|
|
20
|
-
"publishConfig": {
|
|
21
|
-
"access": "public"
|
|
22
|
-
},
|
|
23
|
-
"main": "./dist/index.js",
|
|
24
|
-
"types": "./dist/index.d.ts",
|
|
25
|
-
"exports": {
|
|
26
|
-
".": {
|
|
27
|
-
"types": "./dist/index.d.ts",
|
|
28
|
-
"default": "./dist/index.js"
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"files": [
|
|
32
|
-
"dist",
|
|
33
|
-
"README.md",
|
|
34
|
-
"LICENSE"
|
|
35
|
-
],
|
|
36
|
-
"scripts": {
|
|
37
|
-
"build": "tsc -p tsconfig.build.json",
|
|
38
|
-
"typecheck": "tsc --noEmit",
|
|
39
|
-
"test": "vitest run && node ../../scripts/check-readme-compiles.mjs"
|
|
40
|
-
},
|
|
41
|
-
"devDependencies": {
|
|
42
|
-
"@types/node": "^22.10.5",
|
|
43
|
-
"typescript": "^5.7.3",
|
|
44
|
-
"vitest": "^3.0.5"
|
|
45
|
-
}
|
|
46
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@mnd8t/sdk",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "TypeScript SDK for the Mandate Gateway authority API",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai-agents",
|
|
7
|
+
"authority",
|
|
8
|
+
"payments",
|
|
9
|
+
"policy",
|
|
10
|
+
"evidence",
|
|
11
|
+
"mnd8t"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"homepage": "https://mnd8t.com/docs/sdk",
|
|
15
|
+
"author": "Glencorse Ltd",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=22"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc -p tsconfig.build.json",
|
|
38
|
+
"typecheck": "tsc --noEmit",
|
|
39
|
+
"test": "vitest run && node ../../scripts/check-readme-compiles.mjs"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^22.10.5",
|
|
43
|
+
"typescript": "^5.7.3",
|
|
44
|
+
"vitest": "^3.0.5"
|
|
45
|
+
}
|
|
46
|
+
}
|