@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.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -2
  3. package/dist/accounts.d.ts +23 -0
  4. package/dist/accounts.js +148 -0
  5. package/dist/cards/accounts.d.ts +156 -0
  6. package/dist/cards/accounts.js +346 -0
  7. package/dist/cards/api.d.ts +379 -0
  8. package/dist/cards/api.js +241 -0
  9. package/dist/cards/commitment.d.ts +86 -0
  10. package/dist/cards/commitment.js +288 -0
  11. package/dist/cards/constants.d.ts +160 -0
  12. package/dist/cards/constants.js +163 -0
  13. package/dist/cards/draft.d.ts +57 -0
  14. package/dist/cards/draft.js +131 -0
  15. package/dist/cards/evidence.d.ts +69 -0
  16. package/dist/cards/evidence.js +41 -0
  17. package/dist/cards/hash.d.ts +9 -0
  18. package/dist/cards/hash.js +47 -0
  19. package/dist/cards/index.d.ts +14 -0
  20. package/dist/cards/index.js +14 -0
  21. package/dist/cards/instructions.d.ts +302 -0
  22. package/dist/cards/instructions.js +474 -0
  23. package/dist/cards/layout.d.ts +33 -0
  24. package/dist/cards/layout.js +137 -0
  25. package/dist/cards/math.d.ts +67 -0
  26. package/dist/cards/math.js +138 -0
  27. package/dist/cards/merchants.d.ts +23 -0
  28. package/dist/cards/merchants.js +38 -0
  29. package/dist/cards/pda.d.ts +42 -0
  30. package/dist/cards/pda.js +93 -0
  31. package/dist/cards/private-repayment.d.ts +198 -0
  32. package/dist/cards/private-repayment.js +485 -0
  33. package/dist/cards/redact.d.ts +18 -0
  34. package/dist/cards/redact.js +103 -0
  35. package/dist/cards/tee.d.ts +253 -0
  36. package/dist/cards/tee.js +605 -0
  37. package/dist/cli.d.ts +31 -0
  38. package/dist/cli.js +351 -0
  39. package/dist/client.d.ts +80 -0
  40. package/dist/client.js +493 -0
  41. package/dist/constants.d.ts +44 -0
  42. package/dist/constants.js +43 -0
  43. package/dist/crossmint-adapt.d.ts +43 -0
  44. package/dist/crossmint-adapt.js +68 -0
  45. package/dist/crossmint-order.d.ts +220 -0
  46. package/dist/crossmint-order.js +638 -0
  47. package/dist/delivery.d.ts +66 -0
  48. package/dist/delivery.js +232 -0
  49. package/dist/encoding.d.ts +51 -0
  50. package/dist/encoding.js +128 -0
  51. package/dist/index.d.ts +27 -0
  52. package/dist/index.js +26 -0
  53. package/dist/known-assets.d.ts +30 -0
  54. package/dist/known-assets.js +49 -0
  55. package/dist/mandate-request.d.ts +123 -0
  56. package/dist/mandate-request.js +401 -0
  57. package/dist/mandate.d.ts +44 -0
  58. package/dist/mandate.js +157 -0
  59. package/dist/ops-snapshot.d.ts +157 -0
  60. package/dist/ops-snapshot.js +356 -0
  61. package/dist/payment-request.d.ts +37 -0
  62. package/dist/payment-request.js +218 -0
  63. package/dist/payment.d.ts +40 -0
  64. package/dist/payment.js +214 -0
  65. package/dist/pda.d.ts +13 -0
  66. package/dist/pda.js +36 -0
  67. package/dist/receipt-export.d.ts +55 -0
  68. package/dist/receipt-export.js +149 -0
  69. package/dist/receipt.d.ts +108 -0
  70. package/dist/receipt.js +213 -0
  71. package/dist/solana.d.ts +5 -0
  72. package/dist/solana.js +20 -0
  73. package/dist/token-capabilities.d.ts +9 -0
  74. package/dist/token-capabilities.js +139 -0
  75. package/dist/token.d.ts +18 -0
  76. package/dist/token.js +55 -0
  77. package/dist/transaction-reader.d.ts +10 -0
  78. package/dist/transaction-reader.js +18 -0
  79. package/dist/transaction-v1.d.ts +18 -0
  80. package/dist/transaction-v1.js +73 -0
  81. package/dist/types.d.ts +267 -0
  82. package/dist/types.js +1 -0
  83. package/dist/x402-adapt.d.ts +20 -0
  84. package/dist/x402-adapt.js +62 -0
  85. package/dist/x402-challenge.d.ts +116 -0
  86. package/dist/x402-challenge.js +385 -0
  87. package/dist/x402.d.ts +18 -0
  88. package/dist/x402.js +35 -0
  89. package/package.json +54 -4
package/dist/cli.js ADDED
@@ -0,0 +1,351 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { writeFile } from "node:fs/promises";
4
+ import { resolve } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { Keypair } from "@solana/web3.js";
7
+ import { ChainPayClient } from "./client.js";
8
+ import { address } from "./encoding.js";
9
+ import { buildMandateRequestPayload, encodeMandateRequestLink, mandateRequestSummary, parseHumanTokenAmount, signMandateRequest, } from "./mandate-request.js";
10
+ import { formatOpsAnsi, formatPaymentLookupAnsi, formatPreparePolicyAnsi, formatReceiptListAnsi, loadOpsSnapshot, receiptListFromSnapshot, receiptUrlForAddress, tokenLabel, } from "./ops-snapshot.js";
11
+ import { assetLabel } from "./known-assets.js";
12
+ import { receiptPolicy, receiptsToCsv } from "./receipt-export.js";
13
+ const VALUE_FLAGS = {
14
+ "--owner": "owner",
15
+ "--mandate": "mandate",
16
+ "--rpc": "rpc",
17
+ "--program": "program",
18
+ "--out": "out",
19
+ "--keypair": "keypair",
20
+ "--mint": "mint",
21
+ "--recipient": "recipient",
22
+ "--agent": "agent",
23
+ "--per-payment": "perPayment",
24
+ "--total": "total",
25
+ "--days": "days",
26
+ "--link-days": "linkDays",
27
+ "--description": "description",
28
+ "--po": "po",
29
+ "--name": "name",
30
+ "--app-url": "appUrl",
31
+ "--decimals": "decimals",
32
+ "--token-program": "tokenProgram",
33
+ };
34
+ /** The default public app, the same one the MCP server links to. */
35
+ export const DEFAULT_APP_URL = "https://chainpay-frontend.onrender.com";
36
+ function usage() {
37
+ return [
38
+ "chainpay — read spend and receipts, and prepare pause/revoke without signing.",
39
+ "",
40
+ "Usage:",
41
+ " chainpay status [--owner <wallet>]",
42
+ " chainpay receipts [--owner <wallet>] [--mandate <pda>]",
43
+ " chainpay receipt <pda>",
44
+ " chainpay export [--owner <wallet>] [--mandate <pda>] [--out <file.csv>]",
45
+ " chainpay pause <mandate> --owner <wallet>",
46
+ " chainpay revoke <mandate> --owner <wallet>",
47
+ " chainpay request-mandate --keypair <file> --mint <mint> --recipient <addr>",
48
+ " --per-payment <amount> --total <amount> --days <n> --description <text>",
49
+ " [--po <id>] [--name <name>] [--app-url <url>]",
50
+ " chainpay request-budget --keypair <file> --agent <addr> --mint <mint>",
51
+ " --total <amount> [--per-payment <amount>] --days <n> --description <text>",
52
+ " [--name <name>] [--app-url <url>]",
53
+ "",
54
+ "Flags: --owner --mandate --rpc --program --out --json --help",
55
+ " export writes receipts as CSV to --out, or to stdout.",
56
+ " --json prints the snapshot, or for pause/revoke the unsigned transaction.",
57
+ " Requests also take --decimals --token-program --link-days (default 7).",
58
+ " Amounts are whole tokens, e.g. 5 or 2.5, converted exactly.",
59
+ "Env: CHAINPAY_OWNER CHAINPAY_RPC_URL CHAINPAY_PROGRAM_ID CHAINPAY_APP_URL",
60
+ "",
61
+ "This CLI never submits a transaction or prints a key. request-mandate and",
62
+ "request-budget sign only an off-chain request with your keypair file; the",
63
+ "owner who opens the link decides the limits and signs in their own wallet.",
64
+ ].join("\n");
65
+ }
66
+ function parseArgs(argv) {
67
+ const flags = {};
68
+ const positional = [];
69
+ for (let index = 0; index < argv.length; index += 1) {
70
+ const arg = argv[index];
71
+ if (arg === "--help" || arg === "-h")
72
+ flags.help = true;
73
+ else if (arg === "--json")
74
+ flags.json = true;
75
+ else if (Object.prototype.hasOwnProperty.call(VALUE_FLAGS, arg)) {
76
+ const value = argv[index + 1];
77
+ if (value === undefined || value === "" || (value.startsWith("-") && arg !== "--description")) {
78
+ throw new Error(`${arg} needs a value`);
79
+ }
80
+ flags[VALUE_FLAGS[arg]] = value;
81
+ index += 1;
82
+ }
83
+ else if (arg.startsWith("-")) {
84
+ throw new Error(`Unknown flag: ${arg}`);
85
+ }
86
+ else {
87
+ positional.push(arg);
88
+ }
89
+ }
90
+ return { command: positional[0] ?? "help", positional: positional.slice(1), flags };
91
+ }
92
+ function clientFrom(flags, env) {
93
+ return new ChainPayClient({
94
+ rpcUrl: flags.rpc ?? env.CHAINPAY_RPC_URL,
95
+ programId: flags.program ?? env.CHAINPAY_PROGRAM_ID,
96
+ commitment: "confirmed",
97
+ });
98
+ }
99
+ function ownerFrom(flags, env) {
100
+ const owner = flags.owner ?? env.CHAINPAY_OWNER;
101
+ if (!owner)
102
+ throw new Error("Pass --owner or set CHAINPAY_OWNER");
103
+ return address(owner);
104
+ }
105
+ function mandateFilterFrom(flags) {
106
+ if (!flags.mandate)
107
+ return undefined;
108
+ const wanted = address(flags.mandate);
109
+ return (mandate) => mandate.address === wanted;
110
+ }
111
+ /** The same shape the MCP pause_mandate tool returns, so a wallet flow can take either. */
112
+ function serializeTransaction(transaction) {
113
+ return {
114
+ feePayer: transaction.feePayer,
115
+ requiredSigners: transaction.requiredSigners,
116
+ instructions: transaction.instructions.map((item) => ({
117
+ name: item.name,
118
+ programId: item.programId,
119
+ keys: item.keys,
120
+ dataBase64: Buffer.from(item.data).toString("base64"),
121
+ })),
122
+ };
123
+ }
124
+ function print(value, text, asJson) {
125
+ if (asJson) {
126
+ process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
127
+ return;
128
+ }
129
+ process.stdout.write(`${text}\n`);
130
+ }
131
+ /**
132
+ * Every receipt under the owner's mandates as one CSV, newest first. Limits
133
+ * come from each receipt's on-chain snapshot or read "not-recorded": the CLI
134
+ * has no relay session, so it never shows a relay observation. Dates come from
135
+ * block time and stay empty when unknown.
136
+ */
137
+ export async function exportReceiptsCsv(client, options) {
138
+ const mandates = (await client.getMandatesByOwner(options.owner))
139
+ .filter((mandate) => !options.mandateFilter || options.mandateFilter(mandate));
140
+ const receipts = (await Promise.all(mandates.map((mandate) => client.getPaymentsByMandate(mandate.address))))
141
+ .flat()
142
+ .sort((left, right) => (right.executedAtSlot > left.executedAtSlot ? 1 : right.executedAtSlot < left.executedAtSlot ? -1 : 0));
143
+ const decimals = new Map();
144
+ await Promise.all([...new Set(receipts.map((receipt) => receipt.mint))].map(async (mint) => {
145
+ decimals.set(mint, await client.getMintDecimals(mint).catch(() => null));
146
+ }));
147
+ const blockTimes = new Map();
148
+ await Promise.all([...new Set(receipts.map((receipt) => receipt.executedAtSlot))].map(async (slot) => {
149
+ blockTimes.set(slot, await client.connection.getBlockTime(Number(slot)).catch(() => null));
150
+ }));
151
+ const rows = receipts.map((receipt) => {
152
+ const verifyUrl = receiptUrlForAddress(receipt.address, options.appUrl);
153
+ return {
154
+ receipt,
155
+ decimals: decimals.get(receipt.mint) ?? null,
156
+ symbol: assetLabel(receipt.mint, receipt.mint),
157
+ blockTime: blockTimes.get(receipt.executedAtSlot) ?? null,
158
+ policy: receiptPolicy(receipt),
159
+ ...(verifyUrl ? { verifyUrl } : {}),
160
+ };
161
+ });
162
+ return { csv: receiptsToCsv(rows), rowCount: rows.length };
163
+ }
164
+ function required(flags, name, flag) {
165
+ const value = flags[name]?.trim();
166
+ if (!value)
167
+ throw new Error(`Pass ${flag}`);
168
+ return value;
169
+ }
170
+ function wholeNumber(value, flag) {
171
+ if (!/^\d+$/.test(value))
172
+ throw new Error(`${flag} must be a whole number`);
173
+ return Number(value);
174
+ }
175
+ /** Solana CLI keypair file: a JSON array of 64 bytes. The secret is never printed. */
176
+ function readKeypairFile(path) {
177
+ let values;
178
+ try {
179
+ values = JSON.parse(readFileSync(path, "utf8"));
180
+ }
181
+ catch {
182
+ throw new Error("Keypair file must be a Solana CLI JSON keypair");
183
+ }
184
+ if (!Array.isArray(values)
185
+ || values.length !== 64
186
+ || !values.every((value) => Number.isInteger(value) && value >= 0 && value <= 255)) {
187
+ throw new Error("Keypair file must be a Solana CLI JSON keypair");
188
+ }
189
+ try {
190
+ return Keypair.fromSecretKey(Uint8Array.from(values));
191
+ }
192
+ catch {
193
+ throw new Error("Keypair file must be a Solana CLI JSON keypair");
194
+ }
195
+ }
196
+ async function runRequestCommand(role, flags, env, deps) {
197
+ const keypairPath = required(flags, "keypair", "--keypair <file>");
198
+ const mint = address(required(flags, "mint", "--mint <mint>"));
199
+ const recipient = role === "vendor" ? address(required(flags, "recipient", "--recipient <addr>")) : undefined;
200
+ const agent = role === "grantee" ? address(required(flags, "agent", "--agent <addr>")) : undefined;
201
+ const total = required(flags, "total", "--total <amount>");
202
+ const perPayment = role === "vendor"
203
+ ? required(flags, "perPayment", "--per-payment <amount>")
204
+ : flags.perPayment?.trim();
205
+ const days = wholeNumber(required(flags, "days", "--days <n>"), "--days");
206
+ const linkValidDays = flags.linkDays === undefined ? undefined : wholeNumber(flags.linkDays, "--link-days");
207
+ const description = required(flags, "description", "--description <text>");
208
+ if (flags.tokenProgram && flags.tokenProgram !== "spl-token" && flags.tokenProgram !== "token-2022") {
209
+ throw new Error("--token-program must be spl-token or token-2022");
210
+ }
211
+ const keypair = readKeypairFile(keypairPath);
212
+ const decimals = flags.decimals === undefined
213
+ ? await deps.getMintDecimals(mint)
214
+ : wholeNumber(flags.decimals, "--decimals");
215
+ const tokenProgram = flags.tokenProgram ?? await deps.getTokenProgram(mint);
216
+ const currentSlot = await deps.getCurrentSlot();
217
+ const totalUnits = parseHumanTokenAmount(total, decimals);
218
+ const payload = buildMandateRequestPayload({
219
+ role,
220
+ requester: keypair.publicKey.toBase58(),
221
+ ...(flags.name ? { requesterName: flags.name } : {}),
222
+ ...(agent ? { agent } : {}),
223
+ ...(recipient ? { recipient } : {}),
224
+ mint,
225
+ tokenProgram,
226
+ total: totalUnits,
227
+ ...(perPayment ? { maxPerPayment: parseHumanTokenAmount(perPayment, decimals) } : {}),
228
+ decimals,
229
+ currentSlot,
230
+ days,
231
+ ...(linkValidDays === undefined ? {} : { linkValidDays }),
232
+ description,
233
+ ...(flags.po ? { poNumber: flags.po } : {}),
234
+ });
235
+ const signed = await signMandateRequest(payload, keypair.secretKey);
236
+ const appUrl = flags.appUrl ?? env.CHAINPAY_APP_URL?.trim() ?? DEFAULT_APP_URL;
237
+ const link = encodeMandateRequestLink(signed, appUrl || DEFAULT_APP_URL);
238
+ const summary = mandateRequestSummary(signed.payload, currentSlot);
239
+ print({ link, summary, request: signed }, `${link}\n\n${summary}\nDays are estimated from 400 ms slots. Nothing moves until the owner signs a mandate.`, flags.json);
240
+ return 0;
241
+ }
242
+ export async function runChainPayCli(argv, env = process.env, requestDeps) {
243
+ const { command, positional, flags } = parseArgs(argv);
244
+ if (flags.help || command === "help" || command === "") {
245
+ process.stdout.write(`${usage()}\n`);
246
+ return 0;
247
+ }
248
+ const appUrl = env.CHAINPAY_APP_URL;
249
+ const client = clientFrom(flags, env);
250
+ if (command === "request-mandate" || command === "request-budget") {
251
+ const deps = requestDeps ?? {
252
+ getCurrentSlot: () => client.getCurrentSlot(),
253
+ getMintDecimals: (mint) => client.getMintDecimals(mint),
254
+ getTokenProgram: (mint) => client.getTokenProgram(mint),
255
+ };
256
+ return runRequestCommand(command === "request-mandate" ? "vendor" : "grantee", flags, env, deps);
257
+ }
258
+ if (command === "status") {
259
+ const owner = ownerFrom(flags, env);
260
+ const snapshot = await loadOpsSnapshot(client, {
261
+ owner,
262
+ mandateFilter: mandateFilterFrom(flags),
263
+ appUrl,
264
+ });
265
+ print(snapshot, formatOpsAnsi(snapshot), flags.json);
266
+ return 0;
267
+ }
268
+ if (command === "receipts") {
269
+ const owner = ownerFrom(flags, env);
270
+ const snapshot = await loadOpsSnapshot(client, {
271
+ owner,
272
+ mandateFilter: mandateFilterFrom(flags),
273
+ appUrl,
274
+ });
275
+ const list = receiptListFromSnapshot(snapshot);
276
+ print(list, formatReceiptListAnsi(list), flags.json);
277
+ return 0;
278
+ }
279
+ if (command === "receipt") {
280
+ const raw = positional[0];
281
+ if (!raw)
282
+ throw new Error("Pass a receipt PDA: chainpay receipt <pda>");
283
+ const receiptAddress = address(raw);
284
+ const proof = await client.readPublicReceipt(receiptAddress);
285
+ const card = {
286
+ kind: "payment_lookup",
287
+ found: proof.receipt.valid,
288
+ receiptAddress,
289
+ ...(proof.receipt.valid
290
+ ? {
291
+ amount: proof.amount?.display,
292
+ symbol: tokenLabel(proof.receipt.receipt.mint),
293
+ status: proof.receipt.receipt.status,
294
+ mandate: proof.receipt.receipt.mandate,
295
+ receiptUrl: receiptUrlForAddress(receiptAddress, appUrl),
296
+ }
297
+ : {}),
298
+ };
299
+ print(card, formatPaymentLookupAnsi(card), flags.json);
300
+ return card.found ? 0 : 1;
301
+ }
302
+ if (command === "export") {
303
+ const owner = ownerFrom(flags, env);
304
+ const { csv, rowCount } = await exportReceiptsCsv(client, {
305
+ owner,
306
+ mandateFilter: mandateFilterFrom(flags),
307
+ appUrl,
308
+ });
309
+ if (flags.out) {
310
+ await writeFile(flags.out, csv, "utf8");
311
+ process.stderr.write(`Wrote ${rowCount} ${rowCount === 1 ? "receipt" : "receipts"} to ${flags.out}\n`);
312
+ }
313
+ else {
314
+ process.stdout.write(csv);
315
+ }
316
+ return 0;
317
+ }
318
+ if (command === "pause" || command === "revoke") {
319
+ const owner = ownerFrom(flags, env);
320
+ const raw = positional[0] ?? flags.mandate;
321
+ if (!raw)
322
+ throw new Error(`Pass a mandate PDA: chainpay ${command} <mandate> --owner <wallet>`);
323
+ const mandate = address(raw);
324
+ const transaction = command === "pause"
325
+ ? client.buildPauseMandate(owner, mandate)
326
+ : client.buildRevokeMandate(owner, mandate);
327
+ const card = {
328
+ action: "owner_wallet_signature_required",
329
+ mandate,
330
+ owner,
331
+ transaction: serializeTransaction(transaction),
332
+ };
333
+ print(card, formatPreparePolicyAnsi(command, mandate), flags.json);
334
+ return 0;
335
+ }
336
+ process.stderr.write(`${usage()}\n`);
337
+ return 1;
338
+ }
339
+ // Compare paths, not URLs: a space in the directory name is percent-encoded in
340
+ // import.meta.url and literal in argv, and a suffix match would also fire for
341
+ // any other package's cli.js that happens to import this module.
342
+ const invokedDirectly = process.argv[1] !== undefined
343
+ && fileURLToPath(import.meta.url) === resolve(process.argv[1]);
344
+ if (invokedDirectly) {
345
+ runChainPayCli(process.argv.slice(2)).then((code) => {
346
+ process.exitCode = code;
347
+ }).catch((error) => {
348
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
349
+ process.exitCode = 1;
350
+ });
351
+ }
@@ -0,0 +1,80 @@
1
+ import { Connection, type Commitment } from "@solana/web3.js";
2
+ import type { Address, AssociatedTokenAccountPreparation, ChainPayClientOptions, Mandate, PaymentReceipt, PaymentSubmissionAdapter, PreparedMandate, PreparedPayment, PreparedTransaction, SupportedAsset, TokenProgram } from "./types.js";
3
+ import { decodeProtocolConfig } from "./accounts.js";
4
+ import { type CreateMandateInput, buildApproveDelegateInstruction, buildUpdateMandateInstruction } from "./mandate.js";
5
+ import { type PreparePaymentInput } from "./payment.js";
6
+ import { type CurrentMandateRead, type PublicReceiptProof, type ReceiptReadResult } from "./receipt.js";
7
+ export type PaymentLookup = Address | {
8
+ mandate: Address;
9
+ invoiceHash: Uint8Array;
10
+ };
11
+ export declare class ChainPayClient {
12
+ readonly connection: Connection;
13
+ readonly programId: Address;
14
+ readonly commitment: Commitment;
15
+ constructor(options?: ChainPayClientOptions | Connection);
16
+ getCurrentSlot(): Promise<bigint>;
17
+ getConfig(): Promise<ReturnType<typeof decodeProtocolConfig> | null>;
18
+ private getMandateCreationMetadata;
19
+ getMandate(mandateAddress: Address): Promise<Mandate | null>;
20
+ getMandatesByOwner(owner: Address): Promise<Mandate[]>;
21
+ getSupportedAsset(mint: Address): Promise<SupportedAsset | null>;
22
+ getSupportedAssets(): Promise<SupportedAsset[]>;
23
+ /**
24
+ * Inspect the canonical token account for one enabled registry asset and,
25
+ * when absent, return an unsigned creation transaction for wallet review.
26
+ */
27
+ prepareAssociatedTokenAccount(input: {
28
+ owner: Address;
29
+ mint: Address;
30
+ payer?: Address;
31
+ }): Promise<AssociatedTokenAccountPreparation>;
32
+ /** Inspect every enabled registry asset. Disabled assets are intentionally excluded. */
33
+ prepareRegisteredAssetTokenAccounts(owner: Address, payer?: Address): Promise<AssociatedTokenAccountPreparation[]>;
34
+ private prepareAssociatedTokenAccountForAsset;
35
+ getPayment(lookup: PaymentLookup): Promise<PaymentReceipt | null>;
36
+ /**
37
+ * Current mandate account fields only. Does not page creation history or
38
+ * load source token metadata. Public verify uses this for optional
39
+ * enrichment; failure must not invalidate a settled receipt.
40
+ */
41
+ getCurrentMandateFields(mandateAddress: Address): Promise<CurrentMandateRead>;
42
+ getVerifiedSettledPayment(receiptAddress: Address): Promise<ReceiptReadResult>;
43
+ readPublicReceipt(receiptAddress: Address): Promise<PublicReceiptProof>;
44
+ getPaymentsByMandate(mandateAddress: Address): Promise<PaymentReceipt[]>;
45
+ getTokenProgram(accountAddress: Address): Promise<TokenProgram>;
46
+ getMintDecimals(mint: Address): Promise<number>;
47
+ buildCreateMandate(input: CreateMandateInput, owner: Address): Promise<PreparedMandate>;
48
+ buildInitializeConfig(supportedMints: readonly Address[], authority: Address): PreparedTransaction;
49
+ buildUpdateMandate(input: Parameters<typeof buildUpdateMandateInstruction>[0], owner: Address, mandateAddress?: Address): PreparedTransaction;
50
+ buildRegisterAsset(mint: Address, tokenProgram: TokenProgram, authority: Address): PreparedTransaction;
51
+ buildSetAssetStatus(mint: Address, authority: Address, enabled: boolean): PreparedTransaction;
52
+ buildPauseMandate(owner: Address, mandateAddress?: Address): PreparedTransaction;
53
+ buildRevokeMandate(owner: Address, mandateAddress?: Address): PreparedTransaction;
54
+ buildRevokeDelegate(sourceTokenAccount: Address, owner: Address, tokenProgram: TokenProgram): PreparedTransaction;
55
+ buildApproveDelegate(input: Parameters<typeof buildApproveDelegateInstruction>[0]): PreparedTransaction;
56
+ preparePayment(input: PreparePaymentInput, agent?: Address): Promise<PreparedPayment>;
57
+ executePayment(prepared: PreparedPayment, adapter: PaymentSubmissionAdapter): Promise<{
58
+ status: "submitted" | "confirmed";
59
+ receiptAddress: string;
60
+ signature: string;
61
+ slot: bigint | undefined;
62
+ code?: undefined;
63
+ error?: undefined;
64
+ } | {
65
+ status: "failed";
66
+ receiptAddress: string;
67
+ code: "DuplicateInvoice";
68
+ error: string;
69
+ signature?: undefined;
70
+ slot?: undefined;
71
+ } | {
72
+ status: "failed";
73
+ receiptAddress: string;
74
+ error: string;
75
+ signature?: undefined;
76
+ slot?: undefined;
77
+ code?: undefined;
78
+ }>;
79
+ private getProgramAccount;
80
+ }