@chainpayhq/sdk 0.0.0-stage → 0.1.0
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 -0
- package/README.md +42 -2
- package/dist/accounts.d.ts +23 -0
- package/dist/accounts.js +148 -0
- package/dist/cards/accounts.d.ts +156 -0
- package/dist/cards/accounts.js +346 -0
- package/dist/cards/api.d.ts +379 -0
- package/dist/cards/api.js +241 -0
- package/dist/cards/commitment.d.ts +86 -0
- package/dist/cards/commitment.js +288 -0
- package/dist/cards/constants.d.ts +160 -0
- package/dist/cards/constants.js +163 -0
- package/dist/cards/draft.d.ts +57 -0
- package/dist/cards/draft.js +131 -0
- package/dist/cards/evidence.d.ts +69 -0
- package/dist/cards/evidence.js +41 -0
- package/dist/cards/hash.d.ts +9 -0
- package/dist/cards/hash.js +47 -0
- package/dist/cards/index.d.ts +14 -0
- package/dist/cards/index.js +14 -0
- package/dist/cards/instructions.d.ts +302 -0
- package/dist/cards/instructions.js +474 -0
- package/dist/cards/layout.d.ts +33 -0
- package/dist/cards/layout.js +137 -0
- package/dist/cards/math.d.ts +67 -0
- package/dist/cards/math.js +138 -0
- package/dist/cards/merchants.d.ts +23 -0
- package/dist/cards/merchants.js +38 -0
- package/dist/cards/pda.d.ts +42 -0
- package/dist/cards/pda.js +93 -0
- package/dist/cards/private-repayment.d.ts +198 -0
- package/dist/cards/private-repayment.js +485 -0
- package/dist/cards/redact.d.ts +18 -0
- package/dist/cards/redact.js +103 -0
- package/dist/cards/tee.d.ts +253 -0
- package/dist/cards/tee.js +605 -0
- package/dist/cli.d.ts +31 -0
- package/dist/cli.js +351 -0
- package/dist/client.d.ts +80 -0
- package/dist/client.js +493 -0
- package/dist/constants.d.ts +44 -0
- package/dist/constants.js +43 -0
- package/dist/crossmint-adapt.d.ts +43 -0
- package/dist/crossmint-adapt.js +68 -0
- package/dist/crossmint-order.d.ts +220 -0
- package/dist/crossmint-order.js +638 -0
- package/dist/delivery.d.ts +66 -0
- package/dist/delivery.js +232 -0
- package/dist/encoding.d.ts +51 -0
- package/dist/encoding.js +128 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +26 -0
- package/dist/known-assets.d.ts +30 -0
- package/dist/known-assets.js +49 -0
- package/dist/mandate-request.d.ts +123 -0
- package/dist/mandate-request.js +401 -0
- package/dist/mandate.d.ts +44 -0
- package/dist/mandate.js +157 -0
- package/dist/ops-snapshot.d.ts +157 -0
- package/dist/ops-snapshot.js +356 -0
- package/dist/payment-request.d.ts +37 -0
- package/dist/payment-request.js +218 -0
- package/dist/payment.d.ts +40 -0
- package/dist/payment.js +214 -0
- package/dist/pda.d.ts +13 -0
- package/dist/pda.js +36 -0
- package/dist/receipt-export.d.ts +55 -0
- package/dist/receipt-export.js +149 -0
- package/dist/receipt.d.ts +108 -0
- package/dist/receipt.js +213 -0
- package/dist/solana.d.ts +5 -0
- package/dist/solana.js +20 -0
- package/dist/token-capabilities.d.ts +9 -0
- package/dist/token-capabilities.js +139 -0
- package/dist/token.d.ts +18 -0
- package/dist/token.js +55 -0
- package/dist/transaction-reader.d.ts +10 -0
- package/dist/transaction-reader.js +18 -0
- package/dist/transaction-v1.d.ts +18 -0
- package/dist/transaction-v1.js +73 -0
- package/dist/types.d.ts +267 -0
- package/dist/types.js +1 -0
- package/dist/x402-adapt.d.ts +20 -0
- package/dist/x402-adapt.js +62 -0
- package/dist/x402-challenge.d.ts +116 -0
- package/dist/x402-challenge.js +385 -0
- package/dist/x402.d.ts +18 -0
- package/dist/x402.js +35 -0
- package/package.json +54 -4
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import type { Address } from "../types.js";
|
|
2
|
+
import { type CardPeriod, type CardPolicy, type CheckoutIntent, type Reservation } from "./accounts.js";
|
|
3
|
+
export type SignMessageWallet = {
|
|
4
|
+
publicKey: Address;
|
|
5
|
+
signMessage(message: Uint8Array): Promise<Uint8Array>;
|
|
6
|
+
};
|
|
7
|
+
/** Anything shaped like a Solana wallet adapter or wallet-standard account with signMessage. */
|
|
8
|
+
export type WalletAdapterLike = {
|
|
9
|
+
publicKey: {
|
|
10
|
+
toBase58(): string;
|
|
11
|
+
} | string | null | undefined;
|
|
12
|
+
signMessage?: (message: Uint8Array) => Promise<Uint8Array | {
|
|
13
|
+
signature: Uint8Array;
|
|
14
|
+
} | Array<{
|
|
15
|
+
signature: Uint8Array;
|
|
16
|
+
}>>;
|
|
17
|
+
};
|
|
18
|
+
/** Signer for a server keypair (Axum authorizer, scripts). The secret stays in this closure. */
|
|
19
|
+
export declare function keypairSigner(secretKey: Uint8Array): Promise<SignMessageWallet>;
|
|
20
|
+
/** Signer for a browser wallet (Phantom via wallet adapter, or wallet-standard). */
|
|
21
|
+
export declare function walletAdapterSigner(adapter: WalletAdapterLike): SignMessageWallet;
|
|
22
|
+
export declare function base58Encode(bytes: Uint8Array): string;
|
|
23
|
+
export type TeeSessionOptions = {
|
|
24
|
+
teeUrl?: string;
|
|
25
|
+
fetch?: typeof fetch;
|
|
26
|
+
now?: () => number;
|
|
27
|
+
timeoutMs?: number;
|
|
28
|
+
};
|
|
29
|
+
export declare class TeeAuthError extends Error {
|
|
30
|
+
constructor(message: string);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* One wallet's authenticated connection to the private rollup. Refreshes the
|
|
34
|
+
* token when it is within 24 h of expiry or after any 401. The token is held
|
|
35
|
+
* in a private field and never leaves this object except through
|
|
36
|
+
* `endpoint()`, which exists only to build a Connection for sending
|
|
37
|
+
* owner-signed transactions.
|
|
38
|
+
*/
|
|
39
|
+
export declare class TeeSession {
|
|
40
|
+
#private;
|
|
41
|
+
readonly wallet: Address;
|
|
42
|
+
readonly teeUrl: string;
|
|
43
|
+
private constructor();
|
|
44
|
+
static open(signer: SignMessageWallet, options?: TeeSessionOptions): Promise<TeeSession>;
|
|
45
|
+
get expiresAt(): number;
|
|
46
|
+
needsRefresh(): boolean;
|
|
47
|
+
refresh(): Promise<void>;
|
|
48
|
+
ensureFresh(): Promise<void>;
|
|
49
|
+
/** SECRET: the tokenized RPC URL. Use only to construct a Connection; never log or display it. */
|
|
50
|
+
endpoint(): Promise<string>;
|
|
51
|
+
/** Raw JSON-RPC over the session. Retries once after a 401 with a fresh token. */
|
|
52
|
+
rpc(method: string, params: unknown[]): Promise<{
|
|
53
|
+
httpStatus: number;
|
|
54
|
+
body: unknown;
|
|
55
|
+
}>;
|
|
56
|
+
toJSON(): {
|
|
57
|
+
wallet: string;
|
|
58
|
+
teeUrl: string;
|
|
59
|
+
expiresAt: number;
|
|
60
|
+
token: string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Contract name (§10): open a TEE session for a keypair- or wallet-backed signer. */
|
|
64
|
+
export declare function getTeeSession(wallet: SignMessageWallet, options?: TeeSessionOptions): Promise<TeeSession>;
|
|
65
|
+
export type TeeRawAccount = {
|
|
66
|
+
owner: Address;
|
|
67
|
+
lamports: bigint;
|
|
68
|
+
data: Uint8Array;
|
|
69
|
+
executable: boolean;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* `not_visible` is NOT "missing". The rollup answers a private account the
|
|
73
|
+
* caller may not read exactly like an account that doesn't exist.
|
|
74
|
+
*/
|
|
75
|
+
export type TeeRead<T> = {
|
|
76
|
+
state: "visible";
|
|
77
|
+
account: T;
|
|
78
|
+
slot: bigint;
|
|
79
|
+
} | {
|
|
80
|
+
state: "not_visible";
|
|
81
|
+
slot: bigint | null;
|
|
82
|
+
} | {
|
|
83
|
+
state: "rpc_error";
|
|
84
|
+
code: string;
|
|
85
|
+
};
|
|
86
|
+
export type TeeReadCommitment = "processed" | "confirmed" | "finalized";
|
|
87
|
+
export declare function readTeeAccount(session: TeeSession, address: Address, commitment?: TeeReadCommitment): Promise<TeeRead<TeeRawAccount>>;
|
|
88
|
+
/** Display shape of a policy: cent strings, hex hashes, no bigint. */
|
|
89
|
+
export type CardPolicyView = {
|
|
90
|
+
policyVersion: number;
|
|
91
|
+
authorizer: Address;
|
|
92
|
+
budgetCents: string;
|
|
93
|
+
maxPurchaseCents: string;
|
|
94
|
+
maxPurchasesPerPeriod: number;
|
|
95
|
+
periodSeconds: number;
|
|
96
|
+
currency: string;
|
|
97
|
+
merchantIdHashes: string[];
|
|
98
|
+
mccs: number[];
|
|
99
|
+
expiresAt: string | null;
|
|
100
|
+
recurringAllowed: boolean;
|
|
101
|
+
feeBps: number;
|
|
102
|
+
maxObligationCents: string;
|
|
103
|
+
frozen: boolean;
|
|
104
|
+
freezeReason: CardPolicy["freezeReason"];
|
|
105
|
+
recoveryState: CardPolicy["recoveryState"];
|
|
106
|
+
statementOutstandingCents: string;
|
|
107
|
+
exceptionsOpen: number;
|
|
108
|
+
members: Array<{
|
|
109
|
+
pubkey: Address;
|
|
110
|
+
flags: number;
|
|
111
|
+
}>;
|
|
112
|
+
ledgerSeq: string;
|
|
113
|
+
commitSeq: string;
|
|
114
|
+
};
|
|
115
|
+
export declare function cardPolicyView(policy: CardPolicy): CardPolicyView;
|
|
116
|
+
export declare function readCardPolicy(session: TeeSession, policyAddress: Address, programId?: Address): Promise<TeeRead<CardPolicyView>>;
|
|
117
|
+
export declare function readCardPeriod(session: TeeSession, periodAddress: Address, programId?: Address): Promise<TeeRead<CardPeriod>>;
|
|
118
|
+
export declare function readReservation(session: TeeSession, address: Address, programId?: Address): Promise<TeeRead<Reservation>>;
|
|
119
|
+
export declare function readCheckoutIntent(session: TeeSession, address: Address, programId?: Address): Promise<TeeRead<CheckoutIntent>>;
|
|
120
|
+
/** Budget left this period, only when both accounts are visible to this wallet. */
|
|
121
|
+
export declare function readAvailableCents(session: TeeSession, accounts: {
|
|
122
|
+
policy: Address;
|
|
123
|
+
period: Address;
|
|
124
|
+
}, programId?: Address): Promise<TeeRead<{
|
|
125
|
+
availableCents: string;
|
|
126
|
+
periodIndex: number;
|
|
127
|
+
}>>;
|
|
128
|
+
/** Plain-language status for any read. Never says "missing" for `not_visible`. */
|
|
129
|
+
export declare function describeTeeRead(read: TeeRead<unknown>): string;
|
|
130
|
+
/** Authorizer path (CD-4): anything but a visible read means stop. */
|
|
131
|
+
export declare function requireVisible<T>(read: TeeRead<T>, what: string): T;
|
|
132
|
+
export type TeeMeasurement = {
|
|
133
|
+
mrTd: string;
|
|
134
|
+
rtMr0: string;
|
|
135
|
+
rtMr1: string;
|
|
136
|
+
rtMr2: string;
|
|
137
|
+
/** Optional extra registers. When an allowlist entry pins one, the observed quote must match it too. */
|
|
138
|
+
rtMr3?: string;
|
|
139
|
+
mrOwner?: string;
|
|
140
|
+
label?: string;
|
|
141
|
+
};
|
|
142
|
+
/** What one fresh TDX quote showed. */
|
|
143
|
+
export type TeeQuoteAttestation = {
|
|
144
|
+
/**
|
|
145
|
+
* `verified`: Intel's DCAP signature chain checked and the quote echoes our fresh challenge.
|
|
146
|
+
* `challenge_bound`: the quote echoes our fresh challenge, but its signature chain wasn't checked.
|
|
147
|
+
*/
|
|
148
|
+
hardware: "verified" | "challenge_bound";
|
|
149
|
+
measurements: TeeMeasurement;
|
|
150
|
+
};
|
|
151
|
+
export type TeeIntegrityProvider = {
|
|
152
|
+
/** Fresh-challenge quote check (genuine TDX hardware). Throws on failure. */
|
|
153
|
+
verifyRpcIntegrity(teeUrl: string): Promise<void>;
|
|
154
|
+
verifyIntegrity?(teeUrl: string): Promise<void>;
|
|
155
|
+
/** Parse MRTD/RTMR0-2 from a fresh quote. Optional: only needed once an allowlist exists. */
|
|
156
|
+
readMeasurements?(teeUrl: string): Promise<TeeMeasurement>;
|
|
157
|
+
/**
|
|
158
|
+
* Preferred: one fresh quote gives both the hardware verdict and the measurements,
|
|
159
|
+
* so the build we compare is the one whose signature was checked. Throws on failure.
|
|
160
|
+
*/
|
|
161
|
+
attestQuote?(teeUrl: string): Promise<TeeQuoteAttestation>;
|
|
162
|
+
};
|
|
163
|
+
export type AttestationMode = "report" | "enforce";
|
|
164
|
+
export type AttestationResult = {
|
|
165
|
+
mode: AttestationMode;
|
|
166
|
+
hardware: "verified" | "challenge_bound" | "failed";
|
|
167
|
+
measurements: "matched" | "mismatch" | "pending" | "unavailable";
|
|
168
|
+
/** Whether an authorizer may keep approving purchases. */
|
|
169
|
+
ok: boolean;
|
|
170
|
+
label: string;
|
|
171
|
+
checkedAt: string;
|
|
172
|
+
/** Which pinned entry matched (`current` / `previous` label), when one did. */
|
|
173
|
+
matchedLabel?: string;
|
|
174
|
+
};
|
|
175
|
+
export type VerifyTeeOptions = {
|
|
176
|
+
mode: AttestationMode;
|
|
177
|
+
teeUrl?: string;
|
|
178
|
+
/**
|
|
179
|
+
* Allowed workload measurements (current + previous). Omitted: the pinned
|
|
180
|
+
* MagicBlock values for the Devnet TEE, nothing for any other URL. An empty
|
|
181
|
+
* list means "pending" (and fails closed in enforce mode).
|
|
182
|
+
*/
|
|
183
|
+
allowlist?: readonly TeeMeasurement[];
|
|
184
|
+
provider?: TeeIntegrityProvider;
|
|
185
|
+
now?: () => number;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* MagicBlock Devnet TEE validator measurements (gate G-MB).
|
|
189
|
+
*
|
|
190
|
+
* Observed by ChainPay in a fresh quote from devnet-tee.magicblock.app on
|
|
191
|
+
* 2026-10-03 (and again 2026-10-04), then confirmed by MagicBlock directly to
|
|
192
|
+
* Dre on 2026-10-04. That confirmation is not a signed or published source, so
|
|
193
|
+
* the provenance label says so.
|
|
194
|
+
*
|
|
195
|
+
* Rotation: when MagicBlock upgrades the validator, move `current` to
|
|
196
|
+
* `previous`, pin the new values as `current`, and drop `previous` once the
|
|
197
|
+
* old build is gone. Deployments can also pass an extra entry through
|
|
198
|
+
* `teeMeasurementAllowlist(extra)` (Axum: `CARDS_TEE_MEASUREMENTS`; frontend:
|
|
199
|
+
* `VITE_CHAINPAY_TEE_MEASUREMENTS_PREVIOUS`) without a release.
|
|
200
|
+
* Mirrored for Axum in shared/cards/tee-measurements.json (a test keeps them equal).
|
|
201
|
+
*/
|
|
202
|
+
export declare const MAGICBLOCK_DEVNET_TEE_MEASUREMENTS: {
|
|
203
|
+
readonly teeUrl: string;
|
|
204
|
+
readonly validator: Address;
|
|
205
|
+
readonly provenance: string;
|
|
206
|
+
readonly current: Required<Omit<TeeMeasurement, "label">> & {
|
|
207
|
+
label: string;
|
|
208
|
+
};
|
|
209
|
+
readonly previous: (TeeMeasurement & {
|
|
210
|
+
label: string;
|
|
211
|
+
}) | null;
|
|
212
|
+
};
|
|
213
|
+
/** The pinned Devnet allowlist: `current`, then `previous` if a rotation is in progress, then any `extra` entries. */
|
|
214
|
+
export declare function teeMeasurementAllowlist(extra?: readonly TeeMeasurement[]): TeeMeasurement[];
|
|
215
|
+
/**
|
|
216
|
+
* Parse an allowlist (JSON list). Accepts the SDK keys (`mrTd`, `rtMr0`…) and
|
|
217
|
+
* Axum's `CARDS_TEE_MEASUREMENTS` keys (`mrtd`, `rtmr0`…). Rejects anything
|
|
218
|
+
* that isn't 48-byte hex.
|
|
219
|
+
*/
|
|
220
|
+
export declare function parseMeasurementAllowlist(json: string | undefined): TeeMeasurement[];
|
|
221
|
+
/**
|
|
222
|
+
* Read the TD 1.0 report of a TDX quote (v4 or v5 with a TD10 body): MRTD,
|
|
223
|
+
* MROWNER, RTMR0-3 and the 64-byte report data. Parsing only; it proves
|
|
224
|
+
* nothing about who signed the quote.
|
|
225
|
+
*/
|
|
226
|
+
export declare function parseTdxQuote(raw: Uint8Array): {
|
|
227
|
+
measurements: Required<Omit<TeeMeasurement, "label">>;
|
|
228
|
+
reportData: Uint8Array;
|
|
229
|
+
};
|
|
230
|
+
export type TdxQuoteProviderOptions = {
|
|
231
|
+
fetch?: typeof fetch;
|
|
232
|
+
/**
|
|
233
|
+
* Verifies Intel's DCAP signature chain over the raw quote (e.g.
|
|
234
|
+
* `@phala/dcap-qvl` getCollateral + verify). Throws when the quote isn't
|
|
235
|
+
* genuine. Without it the provider reports `challenge_bound` only.
|
|
236
|
+
*/
|
|
237
|
+
verifyQuote?: (raw: Uint8Array) => Promise<void>;
|
|
238
|
+
/** Test hook for the 64-byte challenge. */
|
|
239
|
+
randomBytes?: (length: number) => Uint8Array;
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Attestation from one fresh quote: GET `{tee}/quote?challenge=<base64 64 bytes>`
|
|
243
|
+
* (the endpoint MagicBlock's verifyTeeRpcIntegrity uses), require the report
|
|
244
|
+
* data to equal our challenge, optionally verify the DCAP chain, and return
|
|
245
|
+
* the measurements of that same quote.
|
|
246
|
+
*/
|
|
247
|
+
export declare function createTdxQuoteProvider(options?: TdxQuoteProviderOptions): TeeIntegrityProvider;
|
|
248
|
+
/**
|
|
249
|
+
* Default provider: MagicBlock's own verifiers, loaded only when installed
|
|
250
|
+
* (`@magicblock-labs/ephemeral-rollups-sdk` is optional, not an SDK dependency).
|
|
251
|
+
*/
|
|
252
|
+
export declare function loadMagicBlockIntegrityProvider(): Promise<TeeIntegrityProvider>;
|
|
253
|
+
export declare function verifyTee(options: VerifyTeeOptions): Promise<AttestationResult>;
|