@aifinpay/agent 1.8.4 → 2.0.0-rc.12

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 (97) hide show
  1. package/PAYMENT_RECEIPTS.md +110 -0
  2. package/README.md +93 -35
  3. package/dist/agent.d.ts +6 -1
  4. package/dist/agent.d.ts.map +1 -1
  5. package/dist/agent.js +50 -12
  6. package/dist/agent.js.map +1 -1
  7. package/dist/agentHistory.d.ts +15 -0
  8. package/dist/agentHistory.d.ts.map +1 -0
  9. package/dist/agentHistory.js +47 -0
  10. package/dist/agentHistory.js.map +1 -0
  11. package/dist/agentPassport.d.ts +95 -0
  12. package/dist/agentPassport.d.ts.map +1 -0
  13. package/dist/agentPassport.js +177 -0
  14. package/dist/agentPassport.js.map +1 -0
  15. package/dist/aifp1.d.ts +135 -8
  16. package/dist/aifp1.d.ts.map +1 -1
  17. package/dist/aifp1.js +317 -50
  18. package/dist/aifp1.js.map +1 -1
  19. package/dist/apiUrl.d.ts +3 -0
  20. package/dist/apiUrl.d.ts.map +1 -0
  21. package/dist/apiUrl.js +8 -0
  22. package/dist/apiUrl.js.map +1 -0
  23. package/dist/chains.d.ts +4 -0
  24. package/dist/chains.d.ts.map +1 -0
  25. package/dist/chains.js +24 -0
  26. package/dist/chains.js.map +1 -0
  27. package/dist/deploymentResolver.d.ts +87 -0
  28. package/dist/deploymentResolver.d.ts.map +1 -0
  29. package/dist/deploymentResolver.js +145 -0
  30. package/dist/deploymentResolver.js.map +1 -0
  31. package/dist/facilitators/aifinpay.d.ts +4 -5
  32. package/dist/facilitators/aifinpay.d.ts.map +1 -1
  33. package/dist/facilitators/aifinpay.js +49 -19
  34. package/dist/facilitators/aifinpay.js.map +1 -1
  35. package/dist/facilitators/base.d.ts +12 -1
  36. package/dist/facilitators/base.d.ts.map +1 -1
  37. package/dist/facilitators/detect.d.ts +3 -3
  38. package/dist/facilitators/detect.d.ts.map +1 -1
  39. package/dist/facilitators/detect.js +3 -22
  40. package/dist/facilitators/detect.js.map +1 -1
  41. package/dist/facilitators/standard-x402.d.ts +4 -8
  42. package/dist/facilitators/standard-x402.d.ts.map +1 -1
  43. package/dist/facilitators/standard-x402.js +218 -92
  44. package/dist/facilitators/standard-x402.js.map +1 -1
  45. package/dist/index.d.ts +24 -18
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +22 -34
  48. package/dist/index.js.map +1 -1
  49. package/dist/localIdentity.d.ts +17 -0
  50. package/dist/localIdentity.d.ts.map +1 -0
  51. package/dist/localIdentity.js +81 -0
  52. package/dist/localIdentity.js.map +1 -0
  53. package/dist/settlement.d.ts +198 -0
  54. package/dist/settlement.d.ts.map +1 -0
  55. package/dist/settlement.js +429 -0
  56. package/dist/settlement.js.map +1 -0
  57. package/dist/settlementHttp.d.ts +10 -0
  58. package/dist/settlementHttp.d.ts.map +1 -0
  59. package/dist/settlementHttp.js +70 -0
  60. package/dist/settlementHttp.js.map +1 -0
  61. package/dist/settlementV14.d.ts +136 -0
  62. package/dist/settlementV14.d.ts.map +1 -0
  63. package/dist/settlementV14.js +170 -0
  64. package/dist/settlementV14.js.map +1 -0
  65. package/dist/solanaDeploymentResolver.d.ts +90 -0
  66. package/dist/solanaDeploymentResolver.d.ts.map +1 -0
  67. package/dist/solanaDeploymentResolver.js +143 -0
  68. package/dist/solanaDeploymentResolver.js.map +1 -0
  69. package/dist/solanaV14Deployments.generated.d.ts +35 -0
  70. package/dist/solanaV14Deployments.generated.d.ts.map +1 -0
  71. package/dist/solanaV14Deployments.generated.js +61 -0
  72. package/dist/solanaV14Deployments.generated.js.map +1 -0
  73. package/dist/splitterRoutes.d.ts +120 -0
  74. package/dist/splitterRoutes.d.ts.map +1 -0
  75. package/dist/splitterRoutes.generated.d.ts +22 -0
  76. package/dist/splitterRoutes.generated.d.ts.map +1 -0
  77. package/dist/splitterRoutes.generated.js +459 -0
  78. package/dist/splitterRoutes.generated.js.map +1 -0
  79. package/dist/splitterRoutes.js +73 -0
  80. package/dist/splitterRoutes.js.map +1 -0
  81. package/dist/unifiedAgent.d.ts +28 -18
  82. package/dist/unifiedAgent.d.ts.map +1 -1
  83. package/dist/unifiedAgent.js +85 -325
  84. package/dist/unifiedAgent.js.map +1 -1
  85. package/dist/v14Deployments.generated.d.ts +53 -0
  86. package/dist/v14Deployments.generated.d.ts.map +1 -0
  87. package/dist/v14Deployments.generated.js +89 -0
  88. package/dist/v14Deployments.generated.js.map +1 -0
  89. package/dist/wallet.d.ts +11 -52
  90. package/dist/wallet.d.ts.map +1 -1
  91. package/dist/wallet.js +27 -51
  92. package/dist/wallet.js.map +1 -1
  93. package/package.json +7 -4
  94. package/dist/cli.d.ts +0 -3
  95. package/dist/cli.d.ts.map +0 -1
  96. package/dist/cli.js +0 -127
  97. package/dist/cli.js.map +0 -1
@@ -0,0 +1,136 @@
1
+ /**
2
+ * B2BSplitter v1.4 settlement — the client half.
3
+ *
4
+ * v1.4 inverts who authorises a payment. Through v1.3 the agent built its own
5
+ * calldata and settled unilaterally; the backend verified afterwards. In v1.4
6
+ * both entrypoints go through `_verifyQuote`, which requires a 65-byte ECDSA
7
+ * signature from a SIGN_OPERATOR_ROLE holder. The agent cannot produce one, so
8
+ * the quote arrives already signed and the agent's job is to CHECK it and
9
+ * submit it — never to construct it.
10
+ *
11
+ * That makes this module mostly refusals, and deliberately so. Spec:
12
+ * evm-contract@feat/v14_migration docs/V14_QUOTE_FORMAT.md §8, "SDK / Frontend
13
+ * Responsibilities". Each check below cites the clause it implements, because
14
+ * a check nobody can trace back to a requirement is a check somebody deletes.
15
+ */
16
+ import { type PublicClient, type WalletClient, type Address, type Hex } from "viem";
17
+ /** The Quote struct, exactly as B2BSplitterV14 declares it. Field ORDER is part
18
+ * of the EIP-712 hash — this mirrors _QUOTE_TYPEHASH and must not be reordered. */
19
+ export interface V14Quote {
20
+ payer: Address;
21
+ merchant: Address;
22
+ token: Address;
23
+ grossAmount: string;
24
+ ipCreator: Address;
25
+ validUntil: string;
26
+ orderIdHash: Hex;
27
+ nonce: string;
28
+ routeId: Hex;
29
+ }
30
+ /** What `/v1/quote` returns under `settlement_call` when settlement_version is 1.4. */
31
+ export interface V14SettlementCall {
32
+ chain: string;
33
+ contract: Address;
34
+ splitter_version: "1.4";
35
+ route: string;
36
+ asset: string;
37
+ function: string;
38
+ arg_encoding: "struct+signature";
39
+ field_order: string[];
40
+ value_wei: string;
41
+ args: {
42
+ quote: V14Quote;
43
+ signature: Hex;
44
+ };
45
+ bound_to_payer?: Address;
46
+ nonce_at_signing?: string;
47
+ }
48
+ export declare class V14SettlementError extends Error {
49
+ readonly code: string;
50
+ constructor(code: string, message: string);
51
+ }
52
+ /**
53
+ * Routes this SDK understands, by NAME.
54
+ *
55
+ * §8.7 requires an allow-list and says old SDKs must refuse routes added after
56
+ * they shipped rather than guess. Names rather than hashes because the contract
57
+ * derives one from the other — Profiles.routeId(name) == keccak256(bytes(name)),
58
+ * verified against the deployed Amoy Profiles on 2026-09-02 for both entries —
59
+ * so hardcoding the hashes would be storing a derived value and inviting the
60
+ * two to disagree.
61
+ */
62
+ export declare const KNOWN_V14_ROUTES: readonly ["merchant-aifp1", "agent-x402"];
63
+ export type KnownV14Route = (typeof KNOWN_V14_ROUTES)[number];
64
+ export declare function routeIdOf(name: string): Hex;
65
+ /** name → routeId, for every route this SDK will submit. */
66
+ export declare function knownRouteIds(): Record<Hex, KnownV14Route>;
67
+ export interface V14ValidateOptions {
68
+ /** The off-chain order id, when the caller knows it (§8.3). Omitted means the
69
+ * orderIdHash cannot be checked, and this module says so rather than
70
+ * pretending it verified something. */
71
+ orderId?: string;
72
+ /** The wallet that will send the transaction. §8.2 and the contract's own
73
+ * `payer == msg.sender` make this the difference between a quote that
74
+ * settles and one that reverts after gas. */
75
+ payer?: Address;
76
+ /** Seconds of headroom required before validUntil. A quote that expires while
77
+ * the transaction is in the mempool reverts SignatureExpired and the agent
78
+ * pays for the attempt. */
79
+ minSecondsRemaining?: number;
80
+ nowMs?: number;
81
+ /** Extra route names this deployment understands. Additive only. */
82
+ allowRoutes?: readonly string[];
83
+ }
84
+ /**
85
+ * Read-only structural checks. Success does not authenticate the signer,
86
+ * deployment, fees or treasury and does not authorize settlement.
87
+ *
88
+ * Throws on the first failure with a code, because these are not equivalent:
89
+ * an expired quote should be re-requested, a foreign payer is a caller bug, and
90
+ * an unknown route means this SDK is older than the deployment.
91
+ */
92
+ export declare function validateV14SettlementCall(call: V14SettlementCall, opts?: V14ValidateOptions): {
93
+ route: string;
94
+ expiresInSeconds: number;
95
+ orderIdChecked: boolean;
96
+ };
97
+ /**
98
+ * §8.6 — never re-broadcast a settled quote.
99
+ *
100
+ * The contract keeps two things and they answer different questions:
101
+ * consumedNonce[payer][nonce] has THIS nonce already been spent
102
+ * payerNonce[payer] which nonce the contract will accept next
103
+ *
104
+ * A quote is submittable only if its nonce is unspent AND is the one the
105
+ * contract expects. Two outstanding quotes for one wallet cannot both settle:
106
+ * the second carries a stale nonce and reverts InvalidNonce. That is a property
107
+ * of the contract, so it is reported here rather than discovered on-chain.
108
+ */
109
+ export declare function checkV14Submittable(publicClient: PublicClient, call: V14SettlementCall): Promise<{
110
+ submittable: true;
111
+ } | {
112
+ submittable: false;
113
+ reason: string;
114
+ code: string;
115
+ }>;
116
+ /**
117
+ * v1.4 signing is quarantined. Its current signed Quote omits mutable profile
118
+ * fees and treasury. RPC preflight cannot bind those values at execution time.
119
+ * Keep the exported API for callers to handle the refusal, but provide no
120
+ * bypass: re-enabling requires a contract-bound economics commitment, reviewed
121
+ * deployment/signer/token pins, approval handling and mined-success recovery.
122
+ * Validation and nonce inspection above remain read-only diagnostics.
123
+ */
124
+ export declare function executeV14Settlement(_call: V14SettlementCall, _ctx: {
125
+ publicClient: PublicClient;
126
+ walletClient: WalletClient;
127
+ account: Address;
128
+ orderId?: string;
129
+ minSecondsRemaining?: number;
130
+ /** @deprecated Cannot bypass the v1.4 settlement quarantine. */
131
+ skipPreflight?: boolean;
132
+ }): Promise<{
133
+ hash: Hex;
134
+ route: string;
135
+ }>;
136
+ //# sourceMappingURL=settlementV14.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settlementV14.d.ts","sourceRoot":"","sources":["../src/settlementV14.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * B2BSplitter v1.4 settlement — the client half.
3
+ *
4
+ * v1.4 inverts who authorises a payment. Through v1.3 the agent built its own
5
+ * calldata and settled unilaterally; the backend verified afterwards. In v1.4
6
+ * both entrypoints go through `_verifyQuote`, which requires a 65-byte ECDSA
7
+ * signature from a SIGN_OPERATOR_ROLE holder. The agent cannot produce one, so
8
+ * the quote arrives already signed and the agent's job is to CHECK it and
9
+ * submit it — never to construct it.
10
+ *
11
+ * That makes this module mostly refusals, and deliberately so. Spec:
12
+ * evm-contract@feat/v14_migration docs/V14_QUOTE_FORMAT.md §8, "SDK / Frontend
13
+ * Responsibilities". Each check below cites the clause it implements, because
14
+ * a check nobody can trace back to a requirement is a check somebody deletes.
15
+ */
16
+ import { keccak256, stringToHex, parseAbi, } from "viem";
17
+ export class V14SettlementError extends Error {
18
+ code;
19
+ constructor(code, message) {
20
+ super(message);
21
+ this.name = "V14SettlementError";
22
+ this.code = code;
23
+ }
24
+ }
25
+ /**
26
+ * Routes this SDK understands, by NAME.
27
+ *
28
+ * §8.7 requires an allow-list and says old SDKs must refuse routes added after
29
+ * they shipped rather than guess. Names rather than hashes because the contract
30
+ * derives one from the other — Profiles.routeId(name) == keccak256(bytes(name)),
31
+ * verified against the deployed Amoy Profiles on 2026-09-02 for both entries —
32
+ * so hardcoding the hashes would be storing a derived value and inviting the
33
+ * two to disagree.
34
+ */
35
+ export const KNOWN_V14_ROUTES = ["merchant-aifp1", "agent-x402"];
36
+ export function routeIdOf(name) {
37
+ return keccak256(stringToHex(name));
38
+ }
39
+ /** name → routeId, for every route this SDK will submit. */
40
+ export function knownRouteIds() {
41
+ const out = {};
42
+ for (const n of KNOWN_V14_ROUTES)
43
+ out[routeIdOf(n).toLowerCase()] = n;
44
+ return out;
45
+ }
46
+ const ZERO = "0x0000000000000000000000000000000000000000";
47
+ const lc = (s) => String(s || "").toLowerCase();
48
+ /**
49
+ * Read-only structural checks. Success does not authenticate the signer,
50
+ * deployment, fees or treasury and does not authorize settlement.
51
+ *
52
+ * Throws on the first failure with a code, because these are not equivalent:
53
+ * an expired quote should be re-requested, a foreign payer is a caller bug, and
54
+ * an unknown route means this SDK is older than the deployment.
55
+ */
56
+ export function validateV14SettlementCall(call, opts = {}) {
57
+ const fail = (code, msg) => { throw new V14SettlementError(code, msg); };
58
+ if (!call || typeof call !== "object")
59
+ fail("V14_MALFORMED", "no settlement call");
60
+ if (call.splitter_version !== "1.4") {
61
+ fail("V14_WRONG_VERSION", `expected a v1.4 settlement call, got ${String(call.splitter_version)} — v1.2 and v1.3 settle through a different path`);
62
+ }
63
+ const q = call.args && call.args.quote;
64
+ const sig = call.args && call.args.signature;
65
+ if (!q || !sig)
66
+ fail("V14_MALFORMED", "settlement call carries no quote or no signature");
67
+ // §8.1 — the signature is the whole point. The contract requires exactly 65
68
+ // bytes and reverts InvalidSignatureLength on anything else, after gas.
69
+ if (!/^0x[0-9a-fA-F]{130}$/.test(sig)) {
70
+ fail("V14_BAD_SIGNATURE", `signature must be 65 bytes, got ${(String(sig).length - 2) / 2}`);
71
+ }
72
+ // §8.7 — refuse routes this SDK does not understand rather than submit blind.
73
+ const allowed = { ...knownRouteIds() };
74
+ for (const extra of opts.allowRoutes || [])
75
+ allowed[routeIdOf(extra).toLowerCase()] = extra;
76
+ const route = allowed[lc(q.routeId)];
77
+ if (!route) {
78
+ fail("V14_UNKNOWN_ROUTE", `routeId ${q.routeId} is not one this SDK understands (${Object.values(allowed).join(", ")}). ` +
79
+ `A route added after this SDK shipped is expected — upgrade rather than force it.`);
80
+ }
81
+ // §8.2 — the contract enforces payer == msg.sender. Catching it here costs
82
+ // nothing; catching it on-chain costs the gas of a reverted transaction.
83
+ if (opts.payer && lc(opts.payer) !== lc(q.payer)) {
84
+ fail("V14_WRONG_PAYER", `this quote is signed for ${q.payer} and cannot be settled by ${opts.payer} — request one for your own address`);
85
+ }
86
+ if (call.bound_to_payer && lc(call.bound_to_payer) !== lc(q.payer)) {
87
+ fail("V14_MALFORMED", "bound_to_payer disagrees with the signed quote — do not submit this");
88
+ }
89
+ // §8.3 — hash the order id locally and compare. This is what stops a backend
90
+ // (or anything between it and here) from binding your payment to a different
91
+ // order than the one you asked about.
92
+ let orderIdChecked = false;
93
+ if (opts.orderId !== undefined) {
94
+ if (lc(keccak256(stringToHex(opts.orderId))) !== lc(q.orderIdHash)) {
95
+ fail("V14_ORDER_MISMATCH", `this quote settles a different order: orderIdHash does not match keccak256("${opts.orderId}")`);
96
+ }
97
+ orderIdChecked = true;
98
+ }
99
+ // §8.4 — expiry. Checked with headroom, because the relevant moment is when
100
+ // the transaction is MINED, not when it is signed.
101
+ const now = Math.floor((opts.nowMs ?? Date.now()) / 1000);
102
+ const expiresIn = Number(BigInt(q.validUntil) - BigInt(now));
103
+ const need = opts.minSecondsRemaining ?? 30;
104
+ if (expiresIn <= 0) {
105
+ fail("V14_EXPIRED", `quote expired ${-expiresIn}s ago — request a fresh one, do not submit this`);
106
+ }
107
+ if (expiresIn < need) {
108
+ fail("V14_EXPIRING", `quote expires in ${expiresIn}s, less than the ${need}s of headroom required — ` +
109
+ `it would likely revert SignatureExpired after you have paid gas`);
110
+ }
111
+ // §8.5 — msg.value must equal grossAmount exactly for native. The contract
112
+ // reverts IncorrectNativeValue on any difference, in either direction.
113
+ if (lc(q.token) === ZERO && String(call.value_wei) !== String(q.grossAmount)) {
114
+ fail("V14_VALUE_MISMATCH", `value_wei (${call.value_wei}) must equal the signed grossAmount (${q.grossAmount})`);
115
+ }
116
+ return { route: route, expiresInSeconds: expiresIn, orderIdChecked };
117
+ }
118
+ const NONCE_ABI = parseAbi([
119
+ "function consumedNonce(address,uint256) view returns (bool)",
120
+ "function payerNonce(address) view returns (uint256)",
121
+ "function paused() view returns (bool)",
122
+ ]);
123
+ /**
124
+ * §8.6 — never re-broadcast a settled quote.
125
+ *
126
+ * The contract keeps two things and they answer different questions:
127
+ * consumedNonce[payer][nonce] has THIS nonce already been spent
128
+ * payerNonce[payer] which nonce the contract will accept next
129
+ *
130
+ * A quote is submittable only if its nonce is unspent AND is the one the
131
+ * contract expects. Two outstanding quotes for one wallet cannot both settle:
132
+ * the second carries a stale nonce and reverts InvalidNonce. That is a property
133
+ * of the contract, so it is reported here rather than discovered on-chain.
134
+ */
135
+ export async function checkV14Submittable(publicClient, call) {
136
+ const q = call.args.quote;
137
+ const [spent, expected, paused] = await Promise.all([
138
+ publicClient.readContract({ address: call.contract, abi: NONCE_ABI, functionName: "consumedNonce", args: [q.payer, BigInt(q.nonce)] }),
139
+ publicClient.readContract({ address: call.contract, abi: NONCE_ABI, functionName: "payerNonce", args: [q.payer] }),
140
+ publicClient.readContract({ address: call.contract, abi: NONCE_ABI, functionName: "paused" }),
141
+ ]);
142
+ if (paused) {
143
+ return { submittable: false, code: "V14_PAUSED",
144
+ reason: "the splitter is paused — every settlement reverts until it is unpaused" };
145
+ }
146
+ if (spent) {
147
+ return { submittable: false, code: "V14_ALREADY_SETTLED",
148
+ reason: `nonce ${q.nonce} has already been spent by ${q.payer} — this quote is settled, do not pay twice` };
149
+ }
150
+ if (BigInt(expected) !== BigInt(q.nonce)) {
151
+ return { submittable: false, code: "V14_STALE_NONCE",
152
+ reason: `this quote was signed at nonce ${q.nonce} but the contract now expects ${expected} — ` +
153
+ `another payment from this wallet settled first; request a fresh quote` };
154
+ }
155
+ return { submittable: true };
156
+ }
157
+ /**
158
+ * v1.4 signing is quarantined. Its current signed Quote omits mutable profile
159
+ * fees and treasury. RPC preflight cannot bind those values at execution time.
160
+ * Keep the exported API for callers to handle the refusal, but provide no
161
+ * bypass: re-enabling requires a contract-bound economics commitment, reviewed
162
+ * deployment/signer/token pins, approval handling and mined-success recovery.
163
+ * Validation and nonce inspection above remain read-only diagnostics.
164
+ */
165
+ export async function executeV14Settlement(_call, _ctx) {
166
+ throw new V14SettlementError("V14_SETTLEMENT_DISABLED", "v1.4 settlement is disabled: signed quotes do not bind mutable fees and treasury. " +
167
+ "Use a separately reviewed v1.3 route or wait for the contract and SDK upgrade; " +
168
+ "do not manually submit this quote or automatically fall back to another contract.");
169
+ }
170
+ //# sourceMappingURL=settlementV14.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settlementV14.js","sourceRoot":"","sources":["../src/settlementV14.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * AIFINP-224 — SDK Environment & Protocol Version resolver (Solana).
3
+ *
4
+ * The Solana sibling of deploymentResolver.ts (AIFINP-223). Same idea — one
5
+ * place that answers "which deployment does the SDK use?" given an environment,
6
+ * a network and a requested version — shaped for Solana, where a deployment is
7
+ * a base58 program id + IDL rather than an EVM address record.
8
+ *
9
+ * Two axes, mirroring the EVM resolver:
10
+ * environment — "dev" | "prod". Development supports devnet only; production
11
+ * uses mainnet-beta. Both read their v1.4 artifacts from solana-contract's
12
+ * dev branch (bundled in solanaV14Deployments.generated.ts).
13
+ * version — "v1.4" | "auto" (and "v1.2" is accepted at the type level for
14
+ * parity with EVM). An explicit "v1.4" never silently downgrades.
15
+ *
16
+ * FALLBACK DIFFERS FROM EVM — READ THIS. The EVM resolver falls back v1.4 -> v1.2.
17
+ * Solana has NO v1.2-equivalent splitter: the old program was closed and removed
18
+ * from mainnet, and the SDK never bundled it (it reads the Solana program id at
19
+ * runtime from the bridge's pay_solana challenge). So there is nothing to fall
20
+ * back to. Therefore:
21
+ * - "auto" resolves v1.4 where deployed, and otherwise throws
22
+ * NoSolanaDeploymentError (no invented downgrade).
23
+ * - an explicit "v1.2" always throws SolanaV12UnavailableError, because no
24
+ * Solana v1.2 deployment exists.
25
+ * This is an open product question for Paul: whether the EVM v1.2/v1.4 fallback
26
+ * model should map onto Solana at all. Until a real Solana fallback exists, this
27
+ * resolver refuses to pretend one does.
28
+ *
29
+ * Program ids live in solanaV14Deployments.generated.ts, never inline here —
30
+ * this module is selection logic only.
31
+ */
32
+ import { DeploymentResolverError, type SdkEnvironment } from "./deploymentResolver.js";
33
+ import { type SolanaV14Deployment } from "./solanaV14Deployments.generated.js";
34
+ /** Selectable protocol versions on the request side. "v1.2" exists for parity
35
+ * with the EVM selector but has no Solana deployment behind it. */
36
+ export type SolanaProtocolVersion = "v1.2" | "v1.4";
37
+ /** What a caller may ask for. "auto" (the default) resolves v1.4, or throws if
38
+ * it is not deployed for the environment+network — Solana has no fallback. */
39
+ export type SolanaRequestedVersion = SolanaProtocolVersion | "auto";
40
+ export interface ResolveSolanaDeploymentOptions {
41
+ environment: SdkEnvironment;
42
+ /** Cluster name: "devnet", or "mainnet"/"mainnet-beta". Case-insensitive. */
43
+ network: string;
44
+ /** Defaults to "auto". */
45
+ version?: SolanaRequestedVersion;
46
+ }
47
+ /** The resolved Solana deployment. Only v1.4 is ever returned; the field is
48
+ * kept for symmetry with the EVM resolver's discriminated union. */
49
+ export interface ResolvedSolanaDeployment {
50
+ version: "v1.4";
51
+ environment: SdkEnvironment;
52
+ network: "devnet" | "mainnet";
53
+ programId: string;
54
+ deployment: SolanaV14Deployment;
55
+ }
56
+ /** The development environment was asked for a cluster other than devnet. */
57
+ export declare class UnsupportedSolanaDevNetworkError extends DeploymentResolverError {
58
+ readonly network: string;
59
+ constructor(network: string);
60
+ }
61
+ /** Explicit "v1.4" requested but not deployed for this environment+network.
62
+ * Thrown rather than downgrading. */
63
+ export declare class SolanaVersionUnavailableError extends DeploymentResolverError {
64
+ readonly requested: SolanaProtocolVersion;
65
+ constructor(requested: SolanaProtocolVersion, environment: SdkEnvironment, network: string);
66
+ }
67
+ /** Explicit "v1.2" requested — no Solana v1.2 splitter exists at all. Distinct
68
+ * from SolanaVersionUnavailableError so callers can tell "not on this network"
69
+ * from "does not exist on Solana". */
70
+ export declare class SolanaV12UnavailableError extends DeploymentResolverError {
71
+ constructor();
72
+ }
73
+ /** No Solana v1.4 deployment exists for this environment+network, and Solana
74
+ * has no fallback version. */
75
+ export declare class NoSolanaDeploymentError extends DeploymentResolverError {
76
+ constructor(environment: SdkEnvironment, network: string);
77
+ }
78
+ /** Is a Solana v1.4 deployment available for this environment+network? */
79
+ export declare function isSolanaV14Available(environment: SdkEnvironment, network: string): boolean;
80
+ /**
81
+ * Resolve the Solana deployment the SDK should use. The single source of truth
82
+ * for Solana environment + protocol-version selection.
83
+ *
84
+ * @throws UnsupportedSolanaDevNetworkError dev asked for a non-devnet cluster
85
+ * @throws SolanaV12UnavailableError explicit v1.2 (none exists on Solana)
86
+ * @throws SolanaVersionUnavailableError explicit v1.4 not deployed here
87
+ * @throws NoSolanaDeploymentError auto, but no v1.4 for this env+network
88
+ */
89
+ export declare function resolveSolanaDeployment(options: ResolveSolanaDeploymentOptions): ResolvedSolanaDeployment;
90
+ //# sourceMappingURL=solanaDeploymentResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solanaDeploymentResolver.d.ts","sourceRoot":"","sources":["../src/solanaDeploymentResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,uBAAuB,EAAE,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,qCAAqC,CAAC;AAE7C;oEACoE;AACpE,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpD;+EAC+E;AAC/E,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,GAAG,MAAM,CAAC;AAEpE,MAAM,WAAW,8BAA8B;IAC7C,WAAW,EAAE,cAAc,CAAC;IAC5B,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,sBAAsB,CAAC;CAClC;AAED;qEACqE;AACrE,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,cAAc,CAAC;IAC5B,OAAO,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,mBAAmB,CAAC;CACjC;AAID,6EAA6E;AAC7E,qBAAa,gCAAiC,SAAQ,uBAAuB;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBACb,OAAO,EAAE,MAAM;CAS5B;AAED;sCACsC;AACtC,qBAAa,6BAA8B,SAAQ,uBAAuB;IACxE,QAAQ,CAAC,SAAS,EAAE,qBAAqB,CAAC;gBAExC,SAAS,EAAE,qBAAqB,EAChC,WAAW,EAAE,cAAc,EAC3B,OAAO,EAAE,MAAM;CAUlB;AAED;;uCAEuC;AACvC,qBAAa,yBAA0B,SAAQ,uBAAuB;;CASrE;AAED;+BAC+B;AAC/B,qBAAa,uBAAwB,SAAQ,uBAAuB;gBACtD,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM;CAOzD;AAsBD,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,cAAc,EAC3B,OAAO,EAAE,MAAM,GACd,OAAO,CAET;AAID;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,8BAA8B,GACtC,wBAAwB,CAyC1B"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * AIFINP-224 — SDK Environment & Protocol Version resolver (Solana).
3
+ *
4
+ * The Solana sibling of deploymentResolver.ts (AIFINP-223). Same idea — one
5
+ * place that answers "which deployment does the SDK use?" given an environment,
6
+ * a network and a requested version — shaped for Solana, where a deployment is
7
+ * a base58 program id + IDL rather than an EVM address record.
8
+ *
9
+ * Two axes, mirroring the EVM resolver:
10
+ * environment — "dev" | "prod". Development supports devnet only; production
11
+ * uses mainnet-beta. Both read their v1.4 artifacts from solana-contract's
12
+ * dev branch (bundled in solanaV14Deployments.generated.ts).
13
+ * version — "v1.4" | "auto" (and "v1.2" is accepted at the type level for
14
+ * parity with EVM). An explicit "v1.4" never silently downgrades.
15
+ *
16
+ * FALLBACK DIFFERS FROM EVM — READ THIS. The EVM resolver falls back v1.4 -> v1.2.
17
+ * Solana has NO v1.2-equivalent splitter: the old program was closed and removed
18
+ * from mainnet, and the SDK never bundled it (it reads the Solana program id at
19
+ * runtime from the bridge's pay_solana challenge). So there is nothing to fall
20
+ * back to. Therefore:
21
+ * - "auto" resolves v1.4 where deployed, and otherwise throws
22
+ * NoSolanaDeploymentError (no invented downgrade).
23
+ * - an explicit "v1.2" always throws SolanaV12UnavailableError, because no
24
+ * Solana v1.2 deployment exists.
25
+ * This is an open product question for Paul: whether the EVM v1.2/v1.4 fallback
26
+ * model should map onto Solana at all. Until a real Solana fallback exists, this
27
+ * resolver refuses to pretend one does.
28
+ *
29
+ * Program ids live in solanaV14Deployments.generated.ts, never inline here —
30
+ * this module is selection logic only.
31
+ */
32
+ import { DeploymentResolverError } from "./deploymentResolver.js";
33
+ import { SOLANA_DEV_NETWORKS, SOLANA_V14_DEPLOYMENTS, } from "./solanaV14Deployments.generated.js";
34
+ // ── Errors (parallel to the EVM resolver, Solana-worded) ─────────────────────
35
+ /** The development environment was asked for a cluster other than devnet. */
36
+ export class UnsupportedSolanaDevNetworkError extends DeploymentResolverError {
37
+ network;
38
+ constructor(network) {
39
+ super(`Development environment supports ${SOLANA_DEV_NETWORKS.join(", ")} only; ` +
40
+ `"${network}" is not a supported Solana development cluster. Use ` +
41
+ `environment "prod" for mainnet.`);
42
+ this.name = "UnsupportedSolanaDevNetworkError";
43
+ this.network = network;
44
+ }
45
+ }
46
+ /** Explicit "v1.4" requested but not deployed for this environment+network.
47
+ * Thrown rather than downgrading. */
48
+ export class SolanaVersionUnavailableError extends DeploymentResolverError {
49
+ requested;
50
+ constructor(requested, environment, network) {
51
+ super(`Solana ${requested} is not deployed for ${environment}/${network}. It ` +
52
+ `was requested explicitly, so the SDK will not substitute another ` +
53
+ `version.`);
54
+ this.name = "SolanaVersionUnavailableError";
55
+ this.requested = requested;
56
+ }
57
+ }
58
+ /** Explicit "v1.2" requested — no Solana v1.2 splitter exists at all. Distinct
59
+ * from SolanaVersionUnavailableError so callers can tell "not on this network"
60
+ * from "does not exist on Solana". */
61
+ export class SolanaV12UnavailableError extends DeploymentResolverError {
62
+ constructor() {
63
+ super(`Solana has no v1.2 deployment. The previous Solana program was closed ` +
64
+ `and there is no v1.2-equivalent to fall back to; only v1.4 is available. ` +
65
+ `Use version "v1.4" or "auto".`);
66
+ this.name = "SolanaV12UnavailableError";
67
+ }
68
+ }
69
+ /** No Solana v1.4 deployment exists for this environment+network, and Solana
70
+ * has no fallback version. */
71
+ export class NoSolanaDeploymentError extends DeploymentResolverError {
72
+ constructor(environment, network) {
73
+ super(`No Solana v1.4 deployment is known for ${environment}/${network}, and ` +
74
+ `Solana has no fallback version.`);
75
+ this.name = "NoSolanaDeploymentError";
76
+ }
77
+ }
78
+ // ── Lookups ──────────────────────────────────────────────────────────────────
79
+ /** Normalise a cluster name: lower-cased, and "mainnet-beta" -> "mainnet". */
80
+ function normalizeNetwork(network) {
81
+ const n = network.trim().toLowerCase();
82
+ return n === "mainnet-beta" ? "mainnet" : n;
83
+ }
84
+ /** The v1.4 deployment for this environment+network, or undefined. A record is
85
+ * only valid for the environment it was deployed under: devnet is dev-only and
86
+ * must never resolve under "prod", and vice versa. */
87
+ function findSolanaV14(environment, network) {
88
+ const entry = SOLANA_V14_DEPLOYMENTS[network];
89
+ if (!entry)
90
+ return undefined;
91
+ return entry.environment === environment ? entry : undefined;
92
+ }
93
+ /** Is a Solana v1.4 deployment available for this environment+network? */
94
+ export function isSolanaV14Available(environment, network) {
95
+ return findSolanaV14(environment, normalizeNetwork(network)) !== undefined;
96
+ }
97
+ // ── The resolver ─────────────────────────────────────────────────────────────
98
+ /**
99
+ * Resolve the Solana deployment the SDK should use. The single source of truth
100
+ * for Solana environment + protocol-version selection.
101
+ *
102
+ * @throws UnsupportedSolanaDevNetworkError dev asked for a non-devnet cluster
103
+ * @throws SolanaV12UnavailableError explicit v1.2 (none exists on Solana)
104
+ * @throws SolanaVersionUnavailableError explicit v1.4 not deployed here
105
+ * @throws NoSolanaDeploymentError auto, but no v1.4 for this env+network
106
+ */
107
+ export function resolveSolanaDeployment(options) {
108
+ const { environment } = options;
109
+ if (environment !== "dev" && environment !== "prod") {
110
+ throw new DeploymentResolverError(`Unknown environment "${String(environment)}"; use "dev" or "prod".`);
111
+ }
112
+ const network = normalizeNetwork(options.network);
113
+ const requested = options.version ?? "auto";
114
+ // Development is restricted to devnet, whatever version is asked for. Reject
115
+ // any other development cluster rather than silently resolving mainnet.
116
+ if (environment === "dev" && !SOLANA_DEV_NETWORKS.includes(network)) {
117
+ throw new UnsupportedSolanaDevNetworkError(options.network);
118
+ }
119
+ const v14 = findSolanaV14(environment, network);
120
+ const asV14 = (d) => ({
121
+ version: "v1.4",
122
+ environment,
123
+ network: d.network,
124
+ programId: d.programId,
125
+ deployment: d,
126
+ });
127
+ switch (requested) {
128
+ case "v1.4":
129
+ if (v14)
130
+ return asV14(v14);
131
+ throw new SolanaVersionUnavailableError("v1.4", environment, options.network);
132
+ case "v1.2":
133
+ // No Solana v1.2 deployment exists — there is nothing to return.
134
+ throw new SolanaV12UnavailableError();
135
+ case "auto":
136
+ if (v14)
137
+ return asV14(v14);
138
+ throw new NoSolanaDeploymentError(environment, options.network);
139
+ default:
140
+ throw new DeploymentResolverError(`Unknown version "${String(requested)}"; use "v1.2", "v1.4" or "auto".`);
141
+ }
142
+ }
143
+ //# sourceMappingURL=solanaDeploymentResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solanaDeploymentResolver.js","sourceRoot":"","sources":["../src/solanaDeploymentResolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { SdkEnvironment } from "./deploymentResolver.js";
2
+ /** Solana clusters the resolver understands. `dev` maps to devnet, `prod` to
3
+ * mainnet-beta. */
4
+ export type SolanaNetwork = "devnet" | "mainnet";
5
+ /** A Solana splitter v1.4 deployment, as recorded by the deploy scripts. */
6
+ export interface SolanaV14Deployment {
7
+ network: SolanaNetwork;
8
+ /** Which SDK environment this deployment belongs to: devnet is the dev
9
+ * target, mainnet is prod. */
10
+ environment: SdkEnvironment;
11
+ splitterVersion: "1.4";
12
+ /** Base58 on-chain program id, from the deploy log's "Canonical program ID
13
+ * confirmed" line. Never hardcoded in resolver logic — read from here. */
14
+ programId: string;
15
+ /** IDL metadata (Anchor), for callers that load the IDL. */
16
+ idl: {
17
+ name: string;
18
+ version: string;
19
+ /** Path of the source IDL artifact in solana-contract, for provenance. */
20
+ artifact: string;
21
+ };
22
+ }
23
+ /** Where this table came from, so a build can be traced to a commit. */
24
+ export declare const SOLANA_V14_DEPLOYMENTS_SOURCE: {
25
+ readonly repo: "AiFinPay/solana-contract";
26
+ readonly branch: "dev";
27
+ readonly commit: "8a13d10d6210cd37345f7ae6684068bf849e24b1";
28
+ readonly path: "deployments/splitter_v14/";
29
+ };
30
+ /** Solana v1.4 deployments, keyed by cluster. Devnet is dev-only; mainnet is
31
+ * prod-only. Absence of a cluster here means no v1.4 deployment for it. */
32
+ export declare const SOLANA_V14_DEPLOYMENTS: Record<string, SolanaV14Deployment>;
33
+ /** The single development cluster Solana v1.4 supports today. */
34
+ export declare const SOLANA_DEV_NETWORKS: readonly ["devnet"];
35
+ //# sourceMappingURL=solanaV14Deployments.generated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solanaV14Deployments.generated.d.ts","sourceRoot":"","sources":["../src/solanaV14Deployments.generated.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D;oBACoB;AACpB,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjD,4EAA4E;AAC5E,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,aAAa,CAAC;IACvB;mCAC+B;IAC/B,WAAW,EAAE,cAAc,CAAC;IAC5B,eAAe,EAAE,KAAK,CAAC;IACvB;+EAC2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,GAAG,EAAE;QACH,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,0EAA0E;QAC1E,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,wEAAwE;AACxE,eAAO,MAAM,6BAA6B;;;;;CAKhC,CAAC;AAEX;4EAC4E;AAC5E,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAyBtE,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,mBAAmB,qBAAsB,CAAC"}