@temporalabs/treasury 0.1.1 → 0.1.3

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 (103) hide show
  1. package/NOTICE +4 -2
  2. package/README.md +100 -44
  3. package/THIRD_PARTY_NOTICES.connect-page.md +7836 -0
  4. package/THIRD_PARTY_NOTICES.md +543 -162
  5. package/dist/cli.d.ts +6 -0
  6. package/dist/cli.js +243 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/client.d.ts +366 -239
  9. package/dist/client.js +202 -25
  10. package/dist/client.js.map +1 -1
  11. package/dist/config/earn.d.ts +48 -12
  12. package/dist/config/earn.js +48 -12
  13. package/dist/config/earn.js.map +1 -1
  14. package/dist/connect/ack.d.ts +76 -0
  15. package/dist/connect/ack.js +147 -0
  16. package/dist/connect/ack.js.map +1 -0
  17. package/dist/connect/commands.d.ts +81 -0
  18. package/dist/connect/commands.js +555 -0
  19. package/dist/connect/commands.js.map +1 -0
  20. package/dist/connect/config.d.ts +24 -0
  21. package/dist/connect/config.js +35 -0
  22. package/dist/connect/config.js.map +1 -0
  23. package/dist/connect/gate-solana.d.ts +8 -0
  24. package/dist/connect/gate-solana.js +147 -0
  25. package/dist/connect/gate-solana.js.map +1 -0
  26. package/dist/connect/gate.d.ts +37 -0
  27. package/dist/connect/gate.js +115 -0
  28. package/dist/connect/gate.js.map +1 -0
  29. package/dist/connect/http.d.ts +60 -0
  30. package/dist/connect/http.js +235 -0
  31. package/dist/connect/http.js.map +1 -0
  32. package/dist/connect/open.d.ts +2 -0
  33. package/dist/connect/open.js +35 -0
  34. package/dist/connect/open.js.map +1 -0
  35. package/dist/connect/page.d.ts +5 -0
  36. package/dist/connect/page.js +69 -0
  37. package/dist/connect/page.js.map +1 -0
  38. package/dist/connect/session.d.ts +39 -0
  39. package/dist/connect/session.js +198 -0
  40. package/dist/connect/session.js.map +1 -0
  41. package/dist/connect/solana.d.ts +73 -0
  42. package/dist/connect/solana.js +267 -0
  43. package/dist/connect/solana.js.map +1 -0
  44. package/dist/connect/verify.d.ts +37 -0
  45. package/dist/connect/verify.js +89 -0
  46. package/dist/connect/verify.js.map +1 -0
  47. package/dist/connect-page.js +5143 -0
  48. package/dist/disclosures.d.ts +22 -6
  49. package/dist/disclosures.js +34 -8
  50. package/dist/disclosures.js.map +1 -1
  51. package/dist/earn/commands.d.ts +46 -0
  52. package/dist/earn/commands.js +556 -0
  53. package/dist/earn/commands.js.map +1 -0
  54. package/dist/earn/solana.d.ts +278 -0
  55. package/dist/earn/solana.js +302 -0
  56. package/dist/earn/solana.js.map +1 -0
  57. package/dist/guide.d.ts +15 -0
  58. package/dist/guide.js +50 -0
  59. package/dist/guide.js.map +1 -0
  60. package/dist/links.d.ts +2 -0
  61. package/dist/links.js +40 -14
  62. package/dist/links.js.map +1 -1
  63. package/dist/position.d.ts +9 -6
  64. package/dist/position.js +39 -19
  65. package/dist/position.js.map +1 -1
  66. package/dist/preflight.d.ts +9 -0
  67. package/dist/preflight.js +14 -3
  68. package/dist/preflight.js.map +1 -1
  69. package/dist/quote.js +24 -7
  70. package/dist/quote.js.map +1 -1
  71. package/dist/redact.d.ts +3 -3
  72. package/dist/redact.js +3 -3
  73. package/dist/redact.js.map +1 -1
  74. package/dist/registry-schema.d.ts +82 -5
  75. package/dist/registry-schema.js +105 -15
  76. package/dist/registry-schema.js.map +1 -1
  77. package/dist/registry.d.ts +50 -7
  78. package/dist/registry.js +122 -21
  79. package/dist/registry.js.map +1 -1
  80. package/dist/solana/constants.d.ts +49 -0
  81. package/dist/solana/constants.js +50 -0
  82. package/dist/solana/constants.js.map +1 -0
  83. package/dist/solana/kvault.d.ts +99 -0
  84. package/dist/solana/kvault.js +192 -0
  85. package/dist/solana/kvault.js.map +1 -0
  86. package/dist/solana/layout.d.ts +143 -0
  87. package/dist/solana/layout.js +209 -0
  88. package/dist/solana/layout.js.map +1 -0
  89. package/dist/solana/rpc.d.ts +24 -0
  90. package/dist/solana/rpc.js +66 -0
  91. package/dist/solana/rpc.js.map +1 -0
  92. package/dist/solana/vault.d.ts +153 -0
  93. package/dist/solana/vault.js +324 -0
  94. package/dist/solana/vault.js.map +1 -0
  95. package/dist/{mcp-server.mjs → treasury.mjs} +41101 -49486
  96. package/dist/version.js +5 -10
  97. package/dist/version.js.map +1 -1
  98. package/llms.txt +621 -0
  99. package/package.json +12 -9
  100. package/registry/vaults.json +218 -4
  101. package/dist/mcp/server.d.ts +0 -8
  102. package/dist/mcp/server.js +0 -368
  103. package/dist/mcp/server.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,CAAU,EAAE,GAAG,GAAG,GAAG;IACjD,MAAM,IAAI,GAAG,CAA4F,CAAC;IAC1G,IAAI,CAAS,CAAC;IACd,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClF,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;QACtB,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;IAC3H,CAAC;SAAM,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;;QAC5F,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IACtE,OAAO,SAAS,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5E,CAAC;AAED;;;;;GAKG;AACH,IAAI,YAAY,GAA4B,GAAG,EAAE,CAAC,EAAE,CAAC;AAErD,0FAA0F;AAC1F,MAAM,UAAU,oBAAoB,CAAC,CAA0B;IAC7D,YAAY,GAAG,CAAC,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,aAAa,CAAC,CAAS,EAAE,UAA6B,YAAY,EAAE;IAClF,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QACrC,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,uCAAuC;IAClF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sHAAsH;AACtH,MAAM,UAAU,eAAe,CAAC,CAAS;IACvC,OAAO,aAAa,CAAC,CAAC,CAAC;QACrB,sFAAsF;SACrF,OAAO,CAAC,wCAAwC,EAAE,gBAAgB,CAAC;QACpE,yFAAyF;QACzF,8FAA8F;QAC9F,2FAA2F;QAC3F,yFAAyF;QACzF,kFAAkF;QAClF,mFAAmF;SAClF,OAAO,CACN,+GAA+G,EAC/G,CAAC,CAAC,EAAE,KAAa,EAAE,IAAY,EAAE,EAAE,CACjC,+DAA+D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,iBAAiB,CAC7G;QACD,sDAAsD;SACrD,OAAO,CAAC,yDAAyD,EAAE,gBAAgB,CAAC;SACpF,OAAO,CAAC,kDAAkD,EAAE,EAAE,CAAC;SAC/D,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,CAAU,EAAE,GAAG,GAAG,GAAG;IACjD,MAAM,IAAI,GAAG,CAA4F,CAAC;IAC1G,IAAI,CAAS,CAAC;IACd,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClF,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;QACtB,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;IAC3H,CAAC;SAAM,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;;QAC5F,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IACtE,OAAO,SAAS,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5E,CAAC;AAED;;;;;GAKG;AACH,IAAI,YAAY,GAA4B,GAAG,EAAE,CAAC,EAAE,CAAC;AAErD,uGAAuG;AACvG,MAAM,UAAU,oBAAoB,CAAC,CAA0B;IAC7D,YAAY,GAAG,CAAC,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,aAAa,CAAC,CAAS,EAAE,UAA6B,YAAY,EAAE;IAClF,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QACrC,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,uCAAuC;IAClF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sHAAsH;AACtH,MAAM,UAAU,eAAe,CAAC,CAAS;IACvC,OAAO,aAAa,CAAC,CAAC,CAAC;QACrB,sFAAsF;SACrF,OAAO,CAAC,wCAAwC,EAAE,gBAAgB,CAAC;QACpE,yFAAyF;QACzF,8FAA8F;QAC9F,2FAA2F;QAC3F,yFAAyF;QACzF,kFAAkF;QAClF,mFAAmF;SAClF,OAAO,CACN,+GAA+G,EAC/G,CAAC,CAAC,EAAE,KAAa,EAAE,IAAY,EAAE,EAAE,CACjC,+DAA+D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,iBAAiB,CAC7G;QACD,sDAAsD;SACrD,OAAO,CAAC,yDAAyD,EAAE,gBAAgB,CAAC;SACpF,OAAO,CAAC,kDAAkD,EAAE,EAAE,CAAC;SAC/D,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAC9B,CAAC"}
@@ -8,13 +8,13 @@ export type Chassis = z.infer<typeof chassisSchema>;
8
8
  /**
9
9
  * Which chassis expose a standard ERC-4626 `deposit`/`redeem` to a depositor. Enzyme does not
10
10
  * (`buyShares` via the comptroller), which is what every refusal path in this client is measured
11
- * against: build, pre-flight, the MCP boundary and the default-vault rule all discriminate on it.
11
+ * against: build, pre-flight, the command boundary and the default-vault rule all discriminate on it.
12
12
  */
13
13
  export declare const erc4626Chassis: ReadonlySet<Chassis>;
14
14
  /**
15
15
  * Whose contract the depositor's USDC actually enters.
16
- * - `morpho`: a public third-party Morpho vault, reached directly. No row uses it today (Tempora vaults only).
17
- * - `tempora`: a Tempora fund vault (the product; each fund joins as it goes live).
16
+ * - `morpho`: a public third-party Morpho vault, reached directly. No row uses it today (Tempora Labs vaults only).
17
+ * - `tempora`: a Tempora Labs fund vault (the product; each fund joins as it goes live).
18
18
  */
19
19
  export declare const backendSchema: z.ZodEnum<{
20
20
  morpho: "morpho";
@@ -45,7 +45,7 @@ export declare const vaultEntrySchema: z.ZodObject<{
45
45
  symbol: z.ZodString;
46
46
  name: z.ZodString;
47
47
  warning: z.ZodString;
48
- chainId: z.ZodLiteral<8453>;
48
+ chainId: z.ZodUnion<readonly [z.ZodLiteral<8453>, z.ZodLiteral<42161>, z.ZodLiteral<4663>, z.ZodLiteral<1>, z.ZodLiteral<143>]>;
49
49
  address: z.ZodPipe<z.ZodString & z.ZodType<`0x${string}`, string, z.core.$ZodTypeInternals<`0x${string}`, string>>, z.ZodTransform<`0x${string}`, `0x${string}`>>;
50
50
  chassis: z.ZodEnum<{
51
51
  "morpho-v2": "morpho-v2";
@@ -81,6 +81,49 @@ export declare const vaultEntrySchema: z.ZodObject<{
81
81
  notes: z.ZodDefault<z.ZodArray<z.ZodString>>;
82
82
  }, z.core.$strict>;
83
83
  export type VaultEntry = z.infer<typeof vaultEntrySchema>;
84
+ /**
85
+ * A vault on Solana. Not an EVM row with different values: there is no chain id, no ERC-4626, no
86
+ * checksummed address, and the depositor's shares are an SPL token of their own (`sharesMint`). So it is a
87
+ * schema of its own, in its own list (`solanaVaults`), and `family` says so in the file as well.
88
+ *
89
+ * `depositOpen` is measured the same way as on EVM — a stranger's SIMULATED deposit, here
90
+ * `simulateTransaction` — and stamped with the slot it was taken at.
91
+ */
92
+ export declare const solanaVaultEntrySchema: z.ZodObject<{
93
+ family: z.ZodLiteral<"solana">;
94
+ symbol: z.ZodString;
95
+ name: z.ZodString;
96
+ warning: z.ZodString;
97
+ chain: z.ZodLiteral<"solana">;
98
+ address: z.ZodString & z.ZodType<import("@solana/kit").Address<string>, string, z.core.$ZodTypeInternals<import("@solana/kit").Address<string>, string>>;
99
+ chassis: z.ZodLiteral<"kamino-vault">;
100
+ backend: z.ZodEnum<{
101
+ morpho: "morpho";
102
+ tempora: "tempora";
103
+ }>;
104
+ isDefault: z.ZodDefault<z.ZodBoolean>;
105
+ asset: z.ZodObject<{
106
+ address: z.ZodString & z.ZodType<import("@solana/kit").Address<string>, string, z.core.$ZodTypeInternals<import("@solana/kit").Address<string>, string>>;
107
+ symbol: z.ZodString;
108
+ decimals: z.ZodNumber;
109
+ }, z.core.$strip>;
110
+ sharesMint: z.ZodString & z.ZodType<import("@solana/kit").Address<string>, string, z.core.$ZodTypeInternals<import("@solana/kit").Address<string>, string>>;
111
+ shareDecimals: z.ZodNumber;
112
+ depositOpen: z.ZodObject<{
113
+ open: z.ZodBoolean;
114
+ method: z.ZodLiteral<"simulated-deposit-from-stranger">;
115
+ measuredAtSlot: z.ZodNumber;
116
+ measuredAtIso: z.ZodString;
117
+ reason: z.ZodOptional<z.ZodEnum<{
118
+ REVERTED_OTHER: "REVERTED_OTHER";
119
+ PERMISSIONED: "PERMISSIONED";
120
+ }>>;
121
+ detail: z.ZodOptional<z.ZodString>;
122
+ }, z.core.$strict>;
123
+ deployedAtSlot: z.ZodNumber;
124
+ notes: z.ZodDefault<z.ZodArray<z.ZodString>>;
125
+ }, z.core.$strict>;
126
+ export type SolanaVaultEntry = z.infer<typeof solanaVaultEntrySchema>;
84
127
  export declare const registrySchema: z.ZodObject<{
85
128
  schemaVersion: z.ZodLiteral<1>;
86
129
  reconciledAtIso: z.ZodString;
@@ -88,7 +131,7 @@ export declare const registrySchema: z.ZodObject<{
88
131
  symbol: z.ZodString;
89
132
  name: z.ZodString;
90
133
  warning: z.ZodString;
91
- chainId: z.ZodLiteral<8453>;
134
+ chainId: z.ZodUnion<readonly [z.ZodLiteral<8453>, z.ZodLiteral<42161>, z.ZodLiteral<4663>, z.ZodLiteral<1>, z.ZodLiteral<143>]>;
92
135
  address: z.ZodPipe<z.ZodString & z.ZodType<`0x${string}`, string, z.core.$ZodTypeInternals<`0x${string}`, string>>, z.ZodTransform<`0x${string}`, `0x${string}`>>;
93
136
  chassis: z.ZodEnum<{
94
137
  "morpho-v2": "morpho-v2";
@@ -123,5 +166,39 @@ export declare const registrySchema: z.ZodObject<{
123
166
  deployedAtBlock: z.ZodOptional<z.ZodNumber>;
124
167
  notes: z.ZodDefault<z.ZodArray<z.ZodString>>;
125
168
  }, z.core.$strict>>;
169
+ solanaVaults: z.ZodDefault<z.ZodArray<z.ZodObject<{
170
+ family: z.ZodLiteral<"solana">;
171
+ symbol: z.ZodString;
172
+ name: z.ZodString;
173
+ warning: z.ZodString;
174
+ chain: z.ZodLiteral<"solana">;
175
+ address: z.ZodString & z.ZodType<import("@solana/kit").Address<string>, string, z.core.$ZodTypeInternals<import("@solana/kit").Address<string>, string>>;
176
+ chassis: z.ZodLiteral<"kamino-vault">;
177
+ backend: z.ZodEnum<{
178
+ morpho: "morpho";
179
+ tempora: "tempora";
180
+ }>;
181
+ isDefault: z.ZodDefault<z.ZodBoolean>;
182
+ asset: z.ZodObject<{
183
+ address: z.ZodString & z.ZodType<import("@solana/kit").Address<string>, string, z.core.$ZodTypeInternals<import("@solana/kit").Address<string>, string>>;
184
+ symbol: z.ZodString;
185
+ decimals: z.ZodNumber;
186
+ }, z.core.$strip>;
187
+ sharesMint: z.ZodString & z.ZodType<import("@solana/kit").Address<string>, string, z.core.$ZodTypeInternals<import("@solana/kit").Address<string>, string>>;
188
+ shareDecimals: z.ZodNumber;
189
+ depositOpen: z.ZodObject<{
190
+ open: z.ZodBoolean;
191
+ method: z.ZodLiteral<"simulated-deposit-from-stranger">;
192
+ measuredAtSlot: z.ZodNumber;
193
+ measuredAtIso: z.ZodString;
194
+ reason: z.ZodOptional<z.ZodEnum<{
195
+ REVERTED_OTHER: "REVERTED_OTHER";
196
+ PERMISSIONED: "PERMISSIONED";
197
+ }>>;
198
+ detail: z.ZodOptional<z.ZodString>;
199
+ }, z.core.$strict>;
200
+ deployedAtSlot: z.ZodNumber;
201
+ notes: z.ZodDefault<z.ZodArray<z.ZodString>>;
202
+ }, z.core.$strict>>>;
126
203
  }, z.core.$strict>;
127
204
  export type Registry = z.infer<typeof registrySchema>;
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { getAddress, isAddress } from "viem";
3
+ import { isAddress as isSolanaAddress } from "@solana/kit";
3
4
  // `strict: true` refuses a lowercase or otherwise mis-cased address — the registry is a hand-edited
4
5
  // artifact and a checksum is the one typo detector an address carries.
5
6
  const address = z
@@ -10,13 +11,13 @@ export const chassisSchema = z.enum(["morpho-v2", "fusion", "enzyme"]);
10
11
  /**
11
12
  * Which chassis expose a standard ERC-4626 `deposit`/`redeem` to a depositor. Enzyme does not
12
13
  * (`buyShares` via the comptroller), which is what every refusal path in this client is measured
13
- * against: build, pre-flight, the MCP boundary and the default-vault rule all discriminate on it.
14
+ * against: build, pre-flight, the command boundary and the default-vault rule all discriminate on it.
14
15
  */
15
16
  export const erc4626Chassis = new Set(["morpho-v2", "fusion"]);
16
17
  /**
17
18
  * Whose contract the depositor's USDC actually enters.
18
- * - `morpho`: a public third-party Morpho vault, reached directly. No row uses it today (Tempora vaults only).
19
- * - `tempora`: a Tempora fund vault (the product; each fund joins as it goes live).
19
+ * - `morpho`: a public third-party Morpho vault, reached directly. No row uses it today (Tempora Labs vaults only).
20
+ * - `tempora`: a Tempora Labs fund vault (the product; each fund joins as it goes live).
20
21
  */
21
22
  export const backendSchema = z.enum(["morpho", "tempora"]);
22
23
  /**
@@ -52,11 +53,20 @@ export const vaultEntrySchema = z
52
53
  * than summarising it.
53
54
  */
54
55
  warning: z.string().min(1),
55
- chainId: z.literal(8453),
56
+ /**
57
+ * The chain the vault is on. One literal per chain in `chains` (`src/client.ts`), spelled out so
58
+ * `VaultEntry["chainId"]` stays a union of literals — `registry.test.ts` holds the two lists equal.
59
+ * 🔴 Adding a chain here also needs its row in `CHAIN_INFO` (a compile error until it has one) and
60
+ * in `links.ts`'s explorer map (which throws on a chain it does not know).
61
+ */
62
+ chainId: z.union([z.literal(8453), z.literal(42161), z.literal(4663), z.literal(1), z.literal(143)]),
56
63
  address,
57
64
  chassis: chassisSchema,
58
65
  backend: backendSchema,
59
- /** Exactly one vault in the registry carries this; it is what the tools use when no `vault` is given. */
66
+ /**
67
+ * Exactly one vault PER CHAIN carries this: the vault the tools use when a caller names a chain
68
+ * and no vault. Which chain is used when the caller names neither is `EARN.defaultChain`.
69
+ */
60
70
  isDefault: z.boolean().default(false),
61
71
  asset: z.object({ address, symbol: z.string().min(1), decimals: z.number().int().min(0).max(36) }),
62
72
  /** Measured on-chain via `decimals()`. 18 on Morpho V2 and Enzyme, 8 on Fusion — never assume. */
@@ -86,6 +96,61 @@ export const vaultEntrySchema = z
86
96
  });
87
97
  }
88
98
  });
99
+ /** A Solana account address: base58, exactly as written — base58 is case-sensitive, so it is never normalised. */
100
+ const solanaAddress = z.string().refine((s) => isSolanaAddress(s), { message: "not a Solana address" });
101
+ /**
102
+ * A vault on Solana. Not an EVM row with different values: there is no chain id, no ERC-4626, no
103
+ * checksummed address, and the depositor's shares are an SPL token of their own (`sharesMint`). So it is a
104
+ * schema of its own, in its own list (`solanaVaults`), and `family` says so in the file as well.
105
+ *
106
+ * `depositOpen` is measured the same way as on EVM — a stranger's SIMULATED deposit, here
107
+ * `simulateTransaction` — and stamped with the slot it was taken at.
108
+ */
109
+ export const solanaVaultEntrySchema = z
110
+ .object({
111
+ family: z.literal("solana"),
112
+ /**
113
+ * The ticker every tool takes as `vault`. A Kamino vault's share mint carries no token metadata, so
114
+ * there is no on-chain ticker to read: this one is ASSIGNED here, in the same form as the EVM rows'.
115
+ * `name` IS read on chain (the vault state stores it), and `scripts/registry-check.ts` reconciles it.
116
+ */
117
+ symbol: z.string().min(1).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/),
118
+ name: z.string().min(1),
119
+ warning: z.string().min(1),
120
+ chain: z.literal("solana"),
121
+ /** The vault's state account: the address every instruction names, and the one an explorer opens. */
122
+ address: solanaAddress,
123
+ chassis: z.literal("kamino-vault"),
124
+ backend: backendSchema,
125
+ isDefault: z.boolean().default(false),
126
+ /** The SPL mint the vault takes and pays (`tokenMint` in the vault state). */
127
+ asset: z.object({ address: solanaAddress, symbol: z.string().min(1), decimals: z.number().int().min(0).max(36) }),
128
+ /** The vault's share mint, a PDA of the vault (`sharesMint` in the vault state). */
129
+ sharesMint: solanaAddress,
130
+ shareDecimals: z.number().int().min(0).max(36),
131
+ depositOpen: z
132
+ .object({
133
+ open: z.boolean(),
134
+ method: z.literal("simulated-deposit-from-stranger"),
135
+ measuredAtSlot: z.number().int().positive(),
136
+ measuredAtIso: z.string().datetime(),
137
+ reason: z.enum(["PERMISSIONED", "REVERTED_OTHER"]).optional(),
138
+ detail: z.string().optional(),
139
+ })
140
+ .strict(),
141
+ /** The slot of the transaction that created the vault state. */
142
+ deployedAtSlot: z.number().int().positive(),
143
+ notes: z.array(z.string()).default([]),
144
+ })
145
+ .strict()
146
+ .superRefine((v, ctx) => {
147
+ if (!v.depositOpen.open && !v.depositOpen.reason) {
148
+ ctx.addIssue({ code: "custom", path: ["depositOpen", "reason"], message: "a closed vault must say why" });
149
+ }
150
+ if (v.depositOpen.open && v.depositOpen.reason) {
151
+ ctx.addIssue({ code: "custom", path: ["depositOpen", "reason"], message: "an open vault carries no reason" });
152
+ }
153
+ });
89
154
  export const registrySchema = z
90
155
  .object({
91
156
  schemaVersion: z.literal(1),
@@ -95,23 +160,48 @@ export const registrySchema = z
95
160
  */
96
161
  reconciledAtIso: z.string().datetime(),
97
162
  vaults: z.array(vaultEntrySchema).min(1),
163
+ /** Vaults on Solana; see `solanaVaultEntrySchema`. One default among them, like any chain. */
164
+ solanaVaults: z.array(solanaVaultEntrySchema).default([]),
98
165
  })
99
166
  .strict()
100
167
  .superRefine((r, ctx) => {
101
168
  const symbols = new Set();
102
169
  const addrs = new Set();
103
- const defaults = r.vaults.filter((v) => v.isDefault);
104
- if (defaults.length !== 1) {
105
- ctx.addIssue({ code: "custom", path: ["vaults"], message: `exactly one vault must be isDefault; found ${defaults.length}` });
170
+ // One default PER CHAIN that has a vault: a caller who names a chain and no vault must get an
171
+ // answer on every chain the registry offers, and exactly one.
172
+ for (const chainId of [...new Set(r.vaults.map((v) => v.chainId))]) {
173
+ const defaults = r.vaults.filter((v) => v.chainId === chainId && v.isDefault);
174
+ if (defaults.length !== 1) {
175
+ ctx.addIssue({ code: "custom", path: ["vaults"], message: `exactly one vault per chain must be isDefault; chain ${chainId} has ${defaults.length}` });
176
+ }
177
+ // A default may be WHITELIST_GATED. The
178
+ // pre-flight re-measures access live on every call and refuses a non-member, so
179
+ // a gated default costs an agent a clear refusal, never funds. It must still be a chassis this client
180
+ // can build for, and it may not be closed for any other reason.
181
+ for (const d of defaults) {
182
+ if (!(erc4626Chassis.has(d.chassis) && (d.depositOpen.open || d.depositOpen.reason === "WHITELIST_GATED"))) {
183
+ ctx.addIssue({ code: "custom", path: ["vaults"], message: `the default vault (${d.symbol}) must be ERC-4626 and either measured open or WHITELIST_GATED` });
184
+ }
185
+ }
106
186
  }
107
- const d = defaults[0];
108
- // A default may be WHITELIST_GATED. The
109
- // pre-flight re-measures access live on every call and refuses a non-member, so
110
- // a gated default costs an agent a clear refusal, never funds. It must still be a chassis this client
111
- // can build for, and it may not be closed for any other reason.
112
- if (d && !(erc4626Chassis.has(d.chassis) && (d.depositOpen.open || d.depositOpen.reason === "WHITELIST_GATED"))) {
113
- ctx.addIssue({ code: "custom", path: ["vaults"], message: `the default vault (${d.symbol}) must be ERC-4626 and either measured open or WHITELIST_GATED` });
187
+ if (r.solanaVaults.length > 0) {
188
+ const defaults = r.solanaVaults.filter((v) => v.isDefault);
189
+ if (defaults.length !== 1) {
190
+ ctx.addIssue({ code: "custom", path: ["solanaVaults"], message: `exactly one vault per chain must be isDefault; chain solana has ${defaults.length}` });
191
+ }
192
+ for (const d of defaults) {
193
+ if (!d.depositOpen.open)
194
+ ctx.addIssue({ code: "custom", path: ["solanaVaults"], message: `the default vault (${d.symbol}) on solana must be measured open` });
195
+ }
114
196
  }
197
+ r.solanaVaults.forEach((v, i) => {
198
+ if (symbols.has(v.symbol))
199
+ ctx.addIssue({ code: "custom", path: ["solanaVaults", i, "symbol"], message: `duplicate symbol ${v.symbol}` });
200
+ if (addrs.has(v.address))
201
+ ctx.addIssue({ code: "custom", path: ["solanaVaults", i, "address"], message: `duplicate address ${v.address}` });
202
+ symbols.add(v.symbol);
203
+ addrs.add(v.address);
204
+ });
115
205
  r.vaults.forEach((v, i) => {
116
206
  if (symbols.has(v.symbol))
117
207
  ctx.addIssue({ code: "custom", path: ["vaults", i, "symbol"], message: `duplicate symbol ${v.symbol}` });
@@ -1 +1 @@
1
- {"version":3,"file":"registry-schema.js","sourceRoot":"","sources":["../src/registry-schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry-schema.js","sourceRoot":"","sources":["../src/registry-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAC7C,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,aAAa,CAAC;AAE3D,oGAAoG;AACpG,uEAAuE;AACvE,MAAM,OAAO,GAAG,CAAC;KACd,MAAM,EAAE;KACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAAC;KAC3F,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAEnC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAGvE;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAyB,IAAI,GAAG,CAAU,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;AAG9F;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAG3D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;IACjB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,iCAAiC,CAAC;IACpD,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC5C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,uGAAuG;IACvG,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC5G,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC;KAC9B,MAAM,CAAC;IACN;;;;OAIG;IACH,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,8BAA8B,CAAC;IAC/D,yDAAyD;IACzD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB;;;;;;OAMG;IACH,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B;;;;;OAKG;IACH,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACpG,OAAO;IACP,OAAO,EAAE,aAAa;IACtB,OAAO,EAAE,aAAa;IACtB;;;OAGG;IACH,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;IAClG,kGAAkG;IAClG,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAC9C,WAAW,EAAE,iBAAiB;IAC9B;;;;OAIG;IACH,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACvD,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACvC,CAAC;KACD,MAAM,EAAE;KACR,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;IACtB,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QACjD,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAC,CAAC;IAC5G,CAAC;IACD,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QAC/C,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC,CAAC;IAChH,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QACzD,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,aAAa,CAAC;YACrB,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,yEAAyE;SAC/F,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAIL,kHAAkH;AAClH,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC,CAAC;AAExG;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC;KACpC,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC3B;;;;OAIG;IACH,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,8BAA8B,CAAC;IAC/D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC1B,qGAAqG;IACrG,OAAO,EAAE,aAAa;IACtB,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;IAClC,OAAO,EAAE,aAAa;IACtB,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACrC,8EAA8E;IAC9E,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;IACjH,oFAAoF;IACpF,UAAU,EAAE,aAAa;IACzB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAC9C,WAAW,EAAE,CAAC;SACX,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;QACjB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,iCAAiC,CAAC;QACpD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QAC3C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACpC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,EAAE;QAC7D,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC9B,CAAC;SACD,MAAM,EAAE;IACX,gEAAgE;IAChE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC3C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACvC,CAAC;KACD,MAAM,EAAE;KACR,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;IACtB,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QACjD,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAC,CAAC;IAC5G,CAAC;IACD,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QAC/C,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC,CAAC;IAChH,CAAC;AACH,CAAC,CAAC,CAAC;AAIL,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC;KAC5B,MAAM,CAAC;IACN,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3B;;;OAGG;IACH,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,8FAA8F;IAC9F,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC1D,CAAC;KACD,MAAM,EAAE;KACR,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;IACtB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,8FAA8F;IAC9F,8DAA8D;IAC9D,KAAK,MAAM,OAAO,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;QAC9E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,wDAAwD,OAAO,QAAQ,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACxJ,CAAC;QACD,wCAAwC;QACxC,gFAAgF;QAChF,sGAAsG;QACtG,gEAAgE;QAChE,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,KAAK,iBAAiB,CAAC,CAAC,EAAE,CAAC;gBAC3G,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC,MAAM,gEAAgE,EAAE,CAAC,CAAC;YAC9J,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC3D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,mEAAmE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC1J,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI;gBAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC,MAAM,mCAAmC,EAAE,CAAC,CAAC;QAChK,CAAC;IACH,CAAC;IACD,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,oBAAoB,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC1I,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,qBAAqB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC5I,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACtB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IACH,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACxB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,oBAAoB,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpI,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,qBAAqB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACtI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACtB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,4 +1,5 @@
1
- import { type Registry, type VaultEntry } from "./registry-schema.js";
1
+ import { type Registry, type SolanaVaultEntry, type VaultEntry } from "./registry-schema.js";
2
+ import { type ChainKey, type SupportedChainId } from "./client.js";
2
3
  /** Parses and validates the shipped registry. Throws on any schema violation — a registry that does not parse is not a registry. */
3
4
  export declare function loadRegistry(): Registry;
4
5
  /**
@@ -11,14 +12,56 @@ export declare function loadRegistry(): Registry;
11
12
  export declare function __setRegistryForTests(r: Registry | undefined): void;
12
13
  export declare function listVaults(): VaultEntry[];
13
14
  export declare function getVault(symbol: string): VaultEntry;
15
+ /** The vaults on Solana (`solanaVaults` in the registry). */
16
+ export declare function listSolanaVaults(): SolanaVaultEntry[];
17
+ /** Every chain a caller can name, EVM and Solana, the default chain first: the list a refusal names. */
18
+ export declare function offeredChainKeys(): string[];
19
+ /** One vault on any chain: an EVM row or a Solana row, which every caller must tell apart before using it. */
20
+ export type ResolvedVault = {
21
+ family: "evm";
22
+ vault: VaultEntry;
23
+ } | {
24
+ family: "solana";
25
+ vault: SolanaVaultEntry;
26
+ };
14
27
  /**
15
- * The vault the tools use when the caller names none: `EARN.defaultVault` (config/earn.ts — the
16
- * toggle), which the registry must also mark `isDefault` (the measurement; the schema guarantees exactly
17
- * one and that it is open). A disagreement between the two is refused, never resolved silently.
28
+ * `resolveVault` across chain families: `chain: "solana"`, or a `vault` that is on Solana, resolves to the
29
+ * Solana row; anything else is `resolveVault`, unchanged. The same refusals hold: a vault and a chain that
30
+ * disagree are refused, and the error says which chain the vault is on.
18
31
  */
19
- export declare function defaultVault(): VaultEntry;
20
- /** Resolves an optional ticker to a vault: the named one, or the default. */
21
- export declare function resolveVault(symbol?: string): VaultEntry;
32
+ export declare function resolveAnyVault(symbol?: string, chain?: string): ResolvedVault;
33
+ /** The Solana vaults any account can put money into: measured open. */
34
+ export declare function depositableSolanaVaults(): SolanaVaultEntry[];
35
+ /** The chain used when a caller names neither a chain nor a vault: `EARN.defaultChain`. */
36
+ export declare function defaultChainId(): SupportedChainId;
37
+ /**
38
+ * The chains a caller can name: every supported chain with at least one vault in the registry, the
39
+ * default chain first. A chain this client supports and the registry has no vault on is not
40
+ * offered — there is nothing to do there.
41
+ */
42
+ export declare function offeredChains(): {
43
+ key: ChainKey;
44
+ chainId: SupportedChainId;
45
+ name: string;
46
+ }[];
47
+ /**
48
+ * The vault the tools use on a chain when the caller names none: `EARN.defaultVaultByChain`
49
+ * (config/earn.ts — the toggle), which the registry must also mark `isDefault` (the measurement; the
50
+ * schema guarantees exactly one per chain and that it is open or whitelist-gated). A disagreement
51
+ * between the two is refused, never resolved silently. With no argument: the default chain's.
52
+ */
53
+ export declare function defaultVault(chainId?: SupportedChainId): VaultEntry;
54
+ /**
55
+ * Resolves an optional ticker and an optional chain to ONE vault:
56
+ *
57
+ * neither the default chain's default vault
58
+ * chain only that chain's default vault
59
+ * vault only that vault, on whatever chain it is on
60
+ * both that vault, and it must be on that chain — a disagreement is REFUSED, never
61
+ * resolved by picking one, because the two answers are different contracts on
62
+ * different chains and the caller meant exactly one of them.
63
+ */
64
+ export declare function resolveVault(symbol?: string, chain?: string): VaultEntry;
22
65
  /**
23
66
  * The vaults this client can put money into: ACTIVE, on an ERC-4626 chassis, and MEASURED open.
24
67
  * This is the rule, not a list — the count moves as vaults are provisioned, gated, or retired.
package/dist/registry.js CHANGED
@@ -1,16 +1,22 @@
1
- import { readFileSync, realpathSync } from "node:fs";
2
- import { fileURLToPath, pathToFileURL } from "node:url";
3
1
  import { registrySchema, erc4626Chassis } from "./registry-schema.js";
2
+ import registryJson from "../registry/vaults.json" with { type: "json" };
4
3
  import { EARN } from "./config/earn.js";
5
- // From this file's real path, not a symlink's: see PACKAGE_JSON_URL in version.ts.
6
- const REGISTRY_URL = new URL("../registry/vaults.json", pathToFileURL(realpathSync(fileURLToPath(import.meta.url))));
4
+ import { CHAIN_INFO, chainIdForKey, SOLANA_INFO, supportedChainIds } from "./client.js";
7
5
  let cached;
8
6
  /** Parses and validates the shipped registry. Throws on any schema violation — a registry that does not parse is not a registry. */
9
7
  export function loadRegistry() {
10
8
  if (cached)
11
9
  return cached;
12
- const raw = JSON.parse(readFileSync(fileURLToPath(REGISTRY_URL), "utf8"));
13
- cached = registrySchema.parse(raw);
10
+ const raw = registryJson;
11
+ const parsed = registrySchema.parse(raw);
12
+ // The schema holds one default per chain THAT HAS A VAULT, so it cannot see a registry with no
13
+ // vault on the default chain at all — and then the discovery call itself is what fails, with an
14
+ // error about a chain nobody asked for. Refuse the file here, where the cause can be named.
15
+ const chainId = defaultChainId();
16
+ if (!parsed.vaults.some((v) => v.chainId === chainId)) {
17
+ throw new Error(`the registry has no vault on ${CHAIN_INFO[chainId].name}, which config/earn.ts names as the default chain; add one or change defaultChain`);
18
+ }
19
+ cached = parsed;
14
20
  return cached;
15
21
  }
16
22
  /**
@@ -29,29 +35,124 @@ export function listVaults() {
29
35
  export function getVault(symbol) {
30
36
  const v = loadRegistry().vaults.find((x) => x.symbol === symbol);
31
37
  if (!v) {
32
- const known = loadRegistry()
33
- .vaults.map((x) => x.symbol)
34
- .join(", ");
38
+ if (loadRegistry().solanaVaults.some((x) => x.symbol === symbol)) {
39
+ throw new Error(`vault "${symbol}" is on solana, which this command does not handle`);
40
+ }
41
+ const known = [...loadRegistry().vaults, ...loadRegistry().solanaVaults].map((x) => x.symbol).join(", ");
35
42
  throw new Error(`unknown vault "${symbol}"; known: ${known}`);
36
43
  }
37
44
  return v;
38
45
  }
46
+ /** The vaults on Solana (`solanaVaults` in the registry). */
47
+ export function listSolanaVaults() {
48
+ return loadRegistry().solanaVaults;
49
+ }
50
+ /** Every chain a caller can name, EVM and Solana, the default chain first: the list a refusal names. */
51
+ export function offeredChainKeys() {
52
+ return [...offeredChains().map((c) => c.key), ...(listSolanaVaults().length > 0 ? [SOLANA_INFO.key] : [])];
53
+ }
39
54
  /**
40
- * The vault the tools use when the caller names none: `EARN.defaultVault` (config/earn.ts — the
41
- * toggle), which the registry must also mark `isDefault` (the measurement; the schema guarantees exactly
42
- * one and that it is open). A disagreement between the two is refused, never resolved silently.
55
+ * `resolveVault` across chain families: `chain: "solana"`, or a `vault` that is on Solana, resolves to the
56
+ * Solana row; anything else is `resolveVault`, unchanged. The same refusals hold: a vault and a chain that
57
+ * disagree are refused, and the error says which chain the vault is on.
43
58
  */
44
- export function defaultVault() {
45
- const v = getVault(EARN.defaultVault);
46
- if (!v.isDefault) {
47
- const marked = loadRegistry().vaults.find((x) => x.isDefault)?.symbol ?? "(none)";
48
- throw new Error(`config/earn.ts names "${EARN.defaultVault}" as the default but the registry marks "${marked}"; change both or neither`);
59
+ export function resolveAnyVault(symbol, chain) {
60
+ const sol = symbol ? listSolanaVaults().find((x) => x.symbol === symbol) : undefined;
61
+ if (chain === SOLANA_INFO.key) {
62
+ const vaults = listSolanaVaults();
63
+ if (vaults.length === 0)
64
+ throw new Error(`unknown chain "${chain}"; chains with a vault: ${offeredChainKeys().join(", ")}`);
65
+ if (!symbol)
66
+ return { family: "solana", vault: vaults.find((x) => x.isDefault) };
67
+ if (sol)
68
+ return { family: "solana", vault: sol };
69
+ const evm = getVault(symbol);
70
+ throw new Error(`vault "${symbol}" is on ${CHAIN_INFO[evm.chainId].key}, not solana. Name one or the other: drop \`chain\` to use ${symbol} on ${CHAIN_INFO[evm.chainId].key}, or pick a vault on solana (${vaults.map((x) => x.symbol).join(", ")}).`);
49
71
  }
50
- return v;
72
+ if (sol) {
73
+ if (chain) {
74
+ throw new Error(`vault "${symbol}" is on solana, not ${chain}. Name one or the other: drop \`chain\` to use ${symbol} on solana, or pick a vault on ${chain}.`);
75
+ }
76
+ return { family: "solana", vault: sol };
77
+ }
78
+ return { family: "evm", vault: resolveVault(symbol, chain) };
79
+ }
80
+ /** The Solana vaults any account can put money into: measured open. */
81
+ export function depositableSolanaVaults() {
82
+ return listSolanaVaults().filter((v) => v.depositOpen.open);
83
+ }
84
+ /** The chain used when a caller names neither a chain nor a vault: `EARN.defaultChain`. */
85
+ export function defaultChainId() {
86
+ const id = chainIdForKey(EARN.defaultChain);
87
+ if (id === undefined)
88
+ throw new Error(`config/earn.ts names "${EARN.defaultChain}" as the default chain, which this client does not support`);
89
+ return id;
90
+ }
91
+ /**
92
+ * The chains a caller can name: every supported chain with at least one vault in the registry, the
93
+ * default chain first. A chain this client supports and the registry has no vault on is not
94
+ * offered — there is nothing to do there.
95
+ */
96
+ export function offeredChains() {
97
+ const present = new Set(loadRegistry().vaults.map((v) => v.chainId));
98
+ const first = defaultChainId();
99
+ return supportedChainIds
100
+ .filter((id) => present.has(id))
101
+ .sort((a, b) => (a === first ? -1 : b === first ? 1 : 0)) // stable: the rest keep `supportedChainIds` order
102
+ .map((id) => ({ key: CHAIN_INFO[id].key, chainId: id, name: CHAIN_INFO[id].name }));
51
103
  }
52
- /** Resolves an optional ticker to a vault: the named one, or the default. */
53
- export function resolveVault(symbol) {
54
- return symbol ? getVault(symbol) : defaultVault();
104
+ /**
105
+ * The vault the tools use on a chain when the caller names none: `EARN.defaultVaultByChain`
106
+ * (config/earn.ts — the toggle), which the registry must also mark `isDefault` (the measurement; the
107
+ * schema guarantees exactly one per chain and that it is open or whitelist-gated). A disagreement
108
+ * between the two is refused, never resolved silently. With no argument: the default chain's.
109
+ */
110
+ export function defaultVault(chainId = defaultChainId()) {
111
+ const key = CHAIN_INFO[chainId].key;
112
+ const named = EARN.defaultVaultByChain[key];
113
+ const marked = loadRegistry().vaults.find((x) => x.chainId === chainId && x.isDefault);
114
+ if (marked === undefined) {
115
+ throw new Error(`no vault is offered on ${CHAIN_INFO[chainId].name}; chains with a vault: ${offeredChains().map((c) => c.key).join(", ")}`);
116
+ }
117
+ if (marked.symbol !== named) {
118
+ throw new Error(`config/earn.ts names "${named}" as the default on ${key} but the registry marks "${marked.symbol}"; change both or neither`);
119
+ }
120
+ return marked;
121
+ }
122
+ /**
123
+ * Resolves an optional ticker and an optional chain to ONE vault:
124
+ *
125
+ * neither the default chain's default vault
126
+ * chain only that chain's default vault
127
+ * vault only that vault, on whatever chain it is on
128
+ * both that vault, and it must be on that chain — a disagreement is REFUSED, never
129
+ * resolved by picking one, because the two answers are different contracts on
130
+ * different chains and the caller meant exactly one of them.
131
+ */
132
+ export function resolveVault(symbol, chain) {
133
+ let chainId;
134
+ // An EMPTY string is an omitted argument, for `chain` exactly as for `vault` (`!symbol` below):
135
+ // a host that sends "" for every optional it did not fill must get the default, not a refusal.
136
+ if (chain) {
137
+ if (chain === SOLANA_INFO.key)
138
+ throw new Error(`chain "${chain}" has no ERC-4626 vault; this resolves the EVM vaults only, and the Solana vault is reached through the CLI (\`treasury earn … --chain solana\`)`);
139
+ chainId = chainIdForKey(chain);
140
+ const offered = offeredChains();
141
+ if (chainId === undefined || !offered.some((c) => c.chainId === chainId)) {
142
+ throw new Error(`unknown chain "${chain}"; chains with a vault: ${offeredChainKeys().join(", ")}`);
143
+ }
144
+ }
145
+ if (!symbol)
146
+ return defaultVault(chainId);
147
+ const v = getVault(symbol);
148
+ if (chainId !== undefined && v.chainId !== chainId) {
149
+ const on = loadRegistry()
150
+ .vaults.filter((x) => x.chainId === chainId)
151
+ .map((x) => x.symbol)
152
+ .join(", ");
153
+ throw new Error(`vault "${symbol}" is on ${CHAIN_INFO[v.chainId].key}, not ${chain}. Name one or the other: drop \`chain\` to use ${symbol} on ${CHAIN_INFO[v.chainId].key}, or pick a vault on ${chain} (${on}).`);
154
+ }
155
+ return v;
55
156
  }
56
157
  /**
57
158
  * The vaults this client can put money into: ACTIVE, on an ERC-4626 chassis, and MEASURED open.
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAkC,MAAM,sBAAsB,CAAC;AACtG,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,mFAAmF;AACnF,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,yBAAyB,EAAE,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAErH,IAAI,MAA4B,CAAC;AAEjC,oIAAoI;AACpI,MAAM,UAAU,YAAY;IAC1B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,CAAY,CAAC;IACrF,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,CAAuB;IAC3D,MAAM,GAAG,CAAC,CAAC;AACb,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,YAAY,EAAE,CAAC,MAAM,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAc;IACrC,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IACjE,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,KAAK,GAAG,YAAY,EAAE;aACzB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;aAC3B,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,kBAAkB,MAAM,aAAa,KAAK,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,QAAQ,CAAC;QAClF,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,YAAY,4CAA4C,MAAM,2BAA2B,CAAC,CAAC;IAC3I,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,MAAe;IAC1C,OAAO,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,YAAY,EAAE,CAAC,MAAM,CAAC,MAAM,CACjC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,CAC3D,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}