@tabai/sdk 0.2.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 (204) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +401 -0
  3. package/bin/tab.mjs +23 -0
  4. package/dist/_shared/abi.d.ts +150 -0
  5. package/dist/_shared/abi.d.ts.map +1 -0
  6. package/dist/_shared/abi.js +197 -0
  7. package/dist/_shared/abi.js.map +1 -0
  8. package/dist/_shared/chains.d.ts +118 -0
  9. package/dist/_shared/chains.d.ts.map +1 -0
  10. package/dist/_shared/chains.js +89 -0
  11. package/dist/_shared/chains.js.map +1 -0
  12. package/dist/_shared/hex.d.ts +35 -0
  13. package/dist/_shared/hex.d.ts.map +1 -0
  14. package/dist/_shared/hex.js +40 -0
  15. package/dist/_shared/hex.js.map +1 -0
  16. package/dist/_shared/index.d.ts +14 -0
  17. package/dist/_shared/index.d.ts.map +1 -0
  18. package/dist/_shared/index.js +14 -0
  19. package/dist/_shared/index.js.map +1 -0
  20. package/dist/_shared/keccak256.d.ts +29 -0
  21. package/dist/_shared/keccak256.d.ts.map +1 -0
  22. package/dist/_shared/keccak256.js +145 -0
  23. package/dist/_shared/keccak256.js.map +1 -0
  24. package/dist/_shared/result.d.ts +78 -0
  25. package/dist/_shared/result.d.ts.map +1 -0
  26. package/dist/_shared/result.js +61 -0
  27. package/dist/_shared/result.js.map +1 -0
  28. package/dist/cli/client-config.d.ts +155 -0
  29. package/dist/cli/client-config.d.ts.map +1 -0
  30. package/dist/cli/client-config.js +382 -0
  31. package/dist/cli/client-config.js.map +1 -0
  32. package/dist/cli/connect.d.ts +76 -0
  33. package/dist/cli/connect.d.ts.map +1 -0
  34. package/dist/cli/connect.js +158 -0
  35. package/dist/cli/connect.js.map +1 -0
  36. package/dist/cli/doctor.d.ts +57 -0
  37. package/dist/cli/doctor.d.ts.map +1 -0
  38. package/dist/cli/doctor.js +253 -0
  39. package/dist/cli/doctor.js.map +1 -0
  40. package/dist/cli/index.d.ts +13 -0
  41. package/dist/cli/index.d.ts.map +1 -0
  42. package/dist/cli/index.js +13 -0
  43. package/dist/cli/index.js.map +1 -0
  44. package/dist/cli/main.d.ts +45 -0
  45. package/dist/cli/main.d.ts.map +1 -0
  46. package/dist/cli/main.js +371 -0
  47. package/dist/cli/main.js.map +1 -0
  48. package/dist/errors.d.ts +29 -0
  49. package/dist/errors.d.ts.map +1 -0
  50. package/dist/errors.js +37 -0
  51. package/dist/errors.js.map +1 -0
  52. package/dist/http/client-402.d.ts +243 -0
  53. package/dist/http/client-402.d.ts.map +1 -0
  54. package/dist/http/client-402.js +515 -0
  55. package/dist/http/client-402.js.map +1 -0
  56. package/dist/http/headers.d.ts +173 -0
  57. package/dist/http/headers.d.ts.map +1 -0
  58. package/dist/http/headers.js +284 -0
  59. package/dist/http/headers.js.map +1 -0
  60. package/dist/http/index.d.ts +15 -0
  61. package/dist/http/index.d.ts.map +1 -0
  62. package/dist/http/index.js +15 -0
  63. package/dist/http/index.js.map +1 -0
  64. package/dist/http/metering-claim.d.ts +82 -0
  65. package/dist/http/metering-claim.d.ts.map +1 -0
  66. package/dist/http/metering-claim.js +99 -0
  67. package/dist/http/metering-claim.js.map +1 -0
  68. package/dist/index.d.ts +48 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +51 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/logger.d.ts +40 -0
  73. package/dist/logger.d.ts.map +1 -0
  74. package/dist/logger.js +50 -0
  75. package/dist/logger.js.map +1 -0
  76. package/dist/mcp/assets.d.ts +31 -0
  77. package/dist/mcp/assets.d.ts.map +1 -0
  78. package/dist/mcp/assets.js +78 -0
  79. package/dist/mcp/assets.js.map +1 -0
  80. package/dist/mcp/index.d.ts +19 -0
  81. package/dist/mcp/index.d.ts.map +1 -0
  82. package/dist/mcp/index.js +19 -0
  83. package/dist/mcp/index.js.map +1 -0
  84. package/dist/mcp/json-schema.d.ts +86 -0
  85. package/dist/mcp/json-schema.d.ts.map +1 -0
  86. package/dist/mcp/json-schema.js +215 -0
  87. package/dist/mcp/json-schema.js.map +1 -0
  88. package/dist/mcp/json.d.ts +43 -0
  89. package/dist/mcp/json.d.ts.map +1 -0
  90. package/dist/mcp/json.js +69 -0
  91. package/dist/mcp/json.js.map +1 -0
  92. package/dist/mcp/registry-client.d.ts +88 -0
  93. package/dist/mcp/registry-client.d.ts.map +1 -0
  94. package/dist/mcp/registry-client.js +158 -0
  95. package/dist/mcp/registry-client.js.map +1 -0
  96. package/dist/mcp/schemas.d.ts +82 -0
  97. package/dist/mcp/schemas.d.ts.map +1 -0
  98. package/dist/mcp/schemas.js +493 -0
  99. package/dist/mcp/schemas.js.map +1 -0
  100. package/dist/mcp/server.d.ts +97 -0
  101. package/dist/mcp/server.d.ts.map +1 -0
  102. package/dist/mcp/server.js +285 -0
  103. package/dist/mcp/server.js.map +1 -0
  104. package/dist/mcp/settings.d.ts +90 -0
  105. package/dist/mcp/settings.d.ts.map +1 -0
  106. package/dist/mcp/settings.js +160 -0
  107. package/dist/mcp/settings.js.map +1 -0
  108. package/dist/mcp/toolset.d.ts +231 -0
  109. package/dist/mcp/toolset.d.ts.map +1 -0
  110. package/dist/mcp/toolset.js +760 -0
  111. package/dist/mcp/toolset.js.map +1 -0
  112. package/dist/payments/abi.d.ts +9 -0
  113. package/dist/payments/abi.d.ts.map +1 -0
  114. package/dist/payments/abi.js +17 -0
  115. package/dist/payments/abi.js.map +1 -0
  116. package/dist/payments/config.d.ts +199 -0
  117. package/dist/payments/config.d.ts.map +1 -0
  118. package/dist/payments/config.js +259 -0
  119. package/dist/payments/config.js.map +1 -0
  120. package/dist/payments/index.d.ts +13 -0
  121. package/dist/payments/index.d.ts.map +1 -0
  122. package/dist/payments/index.js +13 -0
  123. package/dist/payments/index.js.map +1 -0
  124. package/dist/payments/kuru.d.ts +191 -0
  125. package/dist/payments/kuru.d.ts.map +1 -0
  126. package/dist/payments/kuru.js +377 -0
  127. package/dist/payments/kuru.js.map +1 -0
  128. package/dist/payments/monad.d.ts +69 -0
  129. package/dist/payments/monad.d.ts.map +1 -0
  130. package/dist/payments/monad.js +306 -0
  131. package/dist/payments/monad.js.map +1 -0
  132. package/dist/payments/permit2.d.ts +118 -0
  133. package/dist/payments/permit2.d.ts.map +1 -0
  134. package/dist/payments/permit2.js +366 -0
  135. package/dist/payments/permit2.js.map +1 -0
  136. package/dist/payments/registry.d.ts +119 -0
  137. package/dist/payments/registry.d.ts.map +1 -0
  138. package/dist/payments/registry.js +199 -0
  139. package/dist/payments/registry.js.map +1 -0
  140. package/dist/payments/strategy.d.ts +80 -0
  141. package/dist/payments/strategy.d.ts.map +1 -0
  142. package/dist/payments/strategy.js +103 -0
  143. package/dist/payments/strategy.js.map +1 -0
  144. package/dist/proxy/hooks.d.ts +90 -0
  145. package/dist/proxy/hooks.d.ts.map +1 -0
  146. package/dist/proxy/hooks.js +35 -0
  147. package/dist/proxy/hooks.js.map +1 -0
  148. package/dist/proxy/index.d.ts +9 -0
  149. package/dist/proxy/index.d.ts.map +1 -0
  150. package/dist/proxy/index.js +9 -0
  151. package/dist/proxy/index.js.map +1 -0
  152. package/dist/proxy/proxy.d.ts +156 -0
  153. package/dist/proxy/proxy.d.ts.map +1 -0
  154. package/dist/proxy/proxy.js +366 -0
  155. package/dist/proxy/proxy.js.map +1 -0
  156. package/dist/server/adapters/express.d.ts +89 -0
  157. package/dist/server/adapters/express.d.ts.map +1 -0
  158. package/dist/server/adapters/express.js +215 -0
  159. package/dist/server/adapters/express.js.map +1 -0
  160. package/dist/server/adapters/hono.d.ts +52 -0
  161. package/dist/server/adapters/hono.d.ts.map +1 -0
  162. package/dist/server/adapters/hono.js +61 -0
  163. package/dist/server/adapters/hono.js.map +1 -0
  164. package/dist/server/adapters/next.d.ts +52 -0
  165. package/dist/server/adapters/next.d.ts.map +1 -0
  166. package/dist/server/adapters/next.js +56 -0
  167. package/dist/server/adapters/next.js.map +1 -0
  168. package/dist/server/index.d.ts +30 -0
  169. package/dist/server/index.d.ts.map +1 -0
  170. package/dist/server/index.js +30 -0
  171. package/dist/server/index.js.map +1 -0
  172. package/dist/server/metering.d.ts +209 -0
  173. package/dist/server/metering.d.ts.map +1 -0
  174. package/dist/server/metering.js +365 -0
  175. package/dist/server/metering.js.map +1 -0
  176. package/dist/server/post-paid.d.ts +355 -0
  177. package/dist/server/post-paid.d.ts.map +1 -0
  178. package/dist/server/post-paid.js +512 -0
  179. package/dist/server/post-paid.js.map +1 -0
  180. package/dist/x402/client.d.ts +203 -0
  181. package/dist/x402/client.d.ts.map +1 -0
  182. package/dist/x402/client.js +337 -0
  183. package/dist/x402/client.js.map +1 -0
  184. package/dist/x402/hub.d.ts +79 -0
  185. package/dist/x402/hub.d.ts.map +1 -0
  186. package/dist/x402/hub.js +164 -0
  187. package/dist/x402/hub.js.map +1 -0
  188. package/dist/x402/index.d.ts +27 -0
  189. package/dist/x402/index.d.ts.map +1 -0
  190. package/dist/x402/index.js +27 -0
  191. package/dist/x402/index.js.map +1 -0
  192. package/dist/x402/proxy.d.ts +162 -0
  193. package/dist/x402/proxy.d.ts.map +1 -0
  194. package/dist/x402/proxy.js +198 -0
  195. package/dist/x402/proxy.js.map +1 -0
  196. package/dist/x402/server.d.ts +162 -0
  197. package/dist/x402/server.d.ts.map +1 -0
  198. package/dist/x402/server.js +306 -0
  199. package/dist/x402/server.js.map +1 -0
  200. package/dist/x402/wire.d.ts +104 -0
  201. package/dist/x402/wire.d.ts.map +1 -0
  202. package/dist/x402/wire.js +265 -0
  203. package/dist/x402/wire.js.map +1 -0
  204. package/package.json +61 -0
@@ -0,0 +1,259 @@
1
+ /**
2
+ * `tab.config.ts` discovery: mechanism three of R23.6.
3
+ *
4
+ * Zero-code wiring. A consumer writes a config file naming strategies as module
5
+ * specifiers, and the strategies register themselves at startup with no
6
+ * application code involved at all:
7
+ *
8
+ * ```ts
9
+ * // tab.config.ts, at the consumer's project root
10
+ * import { defineTabConfig } from "@tabai/sdk";
11
+ * export default defineTabConfig({ strategies: ["@acme/tab-strategy-solana"] });
12
+ * ```
13
+ *
14
+ * ## What an entry may be
15
+ *
16
+ * A module specifier, a strategy object, or a factory returning one. The
17
+ * specifier form is the point of the mechanism; the other two exist because a
18
+ * config file that can only name packages forces a consumer to publish one before
19
+ * they can try anything.
20
+ *
21
+ * ## Where a specifier resolves from
22
+ *
23
+ * From the **config file**, not from this package. `@acme/tab-strategy-solana` is
24
+ * the consumer's dependency and under pnpm it is not visible from inside
25
+ * `@tabai/sdk` at all, so resolving relative to this module would fail for the
26
+ * exact layout the workspace uses. `createRequire(configFileUrl)` resolves the
27
+ * way the consumer's own `import` would, and a bare specifier that resolution
28
+ * misses is retried as a plain dynamic import before the error is reported.
29
+ *
30
+ * ## The `.ts` config file and the host runtime
31
+ *
32
+ * This module imports the config file; it does not compile it. A `.ts` config
33
+ * loads under a runtime that strips types, `tsx`, `node --experimental-strip-types`,
34
+ * a bundler's dev server, and fails under one that does not. That failure comes
35
+ * back as a `Result` naming the file and the requirement rather than as a stack
36
+ * trace, and `tab.config.js` and `tab.config.mjs` are discovered too so a
37
+ * consumer with a plain Node process has a first-class option.
38
+ *
39
+ * Requirements: 23.6, 21.5
40
+ */
41
+ import { existsSync, statSync } from "node:fs";
42
+ import { createRequire } from "node:module";
43
+ import { dirname, isAbsolute, resolve as resolvePath } from "node:path";
44
+ import { pathToFileURL } from "node:url";
45
+ import { causeOf, ok, wrap, wrapSync } from "../_shared/index.js";
46
+ import { defaultLogger } from "../logger.js";
47
+ import { notFoundError, validationError } from "../errors.js";
48
+ import { validatePaymentStrategy } from "./strategy.js";
49
+ import { moduleStrategyRegistry, } from "./registry.js";
50
+ /**
51
+ * Types a config file's default export. Identity at runtime, its whole job is to
52
+ * make a typo in the config a compile error in the consumer's editor.
53
+ */
54
+ export const defineTabConfig = (config) => config;
55
+ /**
56
+ * The file names discovery looks for, in order. `.ts` first because it is the
57
+ * documented form and the one that type-checks; the plain-JavaScript forms follow
58
+ * so a consumer whose runtime strips no types is not shut out.
59
+ */
60
+ export const TAB_CONFIG_FILE_NAMES = [
61
+ "tab.config.ts",
62
+ "tab.config.mts",
63
+ "tab.config.mjs",
64
+ "tab.config.js",
65
+ "tab.config.cjs",
66
+ ];
67
+ /**
68
+ * Walks from `cwd` towards the filesystem root and returns the first config file
69
+ * found, or `undefined` when there is none.
70
+ *
71
+ * Absence is not an error: the whole point of the mechanism is that a consumer
72
+ * who wants nothing from it writes nothing.
73
+ */
74
+ export function findTabConfig(options = {}) {
75
+ return wrapSync(() => {
76
+ const fileNames = options.fileNames ?? TAB_CONFIG_FILE_NAMES;
77
+ let directory = resolvePath(options.cwd ?? ".");
78
+ for (;;) {
79
+ for (const fileName of fileNames) {
80
+ const candidate = resolvePath(directory, fileName);
81
+ if (existsSync(candidate) && statSync(candidate).isFile())
82
+ return candidate;
83
+ }
84
+ const parent = dirname(directory);
85
+ if (parent === directory)
86
+ return undefined;
87
+ directory = parent;
88
+ }
89
+ }, (error) => ({
90
+ category: "INTERNAL",
91
+ code: "CONFIG_SEARCH_FAILED",
92
+ message: "the tab.config search could not read the filesystem",
93
+ retryable: false,
94
+ cause: causeOf(error),
95
+ }));
96
+ }
97
+ const EMPTY_CONFIG = {};
98
+ /**
99
+ * Loads a config file, resolves every strategy entry, and registers the result.
100
+ *
101
+ * Returns a `Result` for every failure, including a config file that throws on
102
+ * import: a consumer's config is consumer code, and this package does not turn
103
+ * their mistake into an unhandled rejection.
104
+ */
105
+ export async function loadTabConfig(options = {}) {
106
+ const logger = options.logger ?? defaultLogger;
107
+ const located = locateConfig(options);
108
+ if (!located.ok)
109
+ return located;
110
+ const path = located.value;
111
+ if (path === undefined) {
112
+ return ok({ path: undefined, config: EMPTY_CONFIG, strategies: [], registrations: [] });
113
+ }
114
+ const imported = await importModule(path, `tab config \`${path}\``);
115
+ if (!imported.ok)
116
+ return imported;
117
+ const config = readDefaultExport(imported.value, path);
118
+ if (!config.ok)
119
+ return config;
120
+ const strategies = [];
121
+ let declined = 0;
122
+ for (const [index, entry] of (config.value.strategies ?? []).entries()) {
123
+ const resolved = await resolveEntry(entry, index, path);
124
+ if (!resolved.ok)
125
+ return resolved;
126
+ // `undefined` is the factory declining, not a fault. Skip it and keep going.
127
+ if (resolved.value === undefined) {
128
+ declined += 1;
129
+ continue;
130
+ }
131
+ strategies.push(resolved.value);
132
+ }
133
+ const registrations = [];
134
+ if (options.registry !== false) {
135
+ const registry = options.registry ?? moduleStrategyRegistry(logger);
136
+ for (const strategy of strategies) {
137
+ const outcome = registry.register(strategy);
138
+ if (!outcome.ok)
139
+ return outcome;
140
+ registrations.push(outcome.value);
141
+ }
142
+ }
143
+ logger.debug("tab config loaded", { path, strategies: strategies.length, declined });
144
+ return ok({ path, config: config.value, strategies, registrations });
145
+ }
146
+ function locateConfig(options) {
147
+ if (options.configPath === undefined)
148
+ return findTabConfig(options);
149
+ const cwd = resolvePath(options.cwd ?? ".");
150
+ const path = isAbsolute(options.configPath)
151
+ ? options.configPath
152
+ : resolvePath(cwd, options.configPath);
153
+ if (!existsSync(path)) {
154
+ return notFoundError("CONFIG_NOT_FOUND", `no tab config file at \`${path}\``, {
155
+ details: { path },
156
+ });
157
+ }
158
+ return ok(path);
159
+ }
160
+ /** Imports a file by path. A `.ts` file needs a type-stripping runtime, so say so. */
161
+ async function importModule(path, label) {
162
+ const href = pathToFileURL(path).href;
163
+ return wrap(async () => (await import(href)), (error) => ({
164
+ category: "UPSTREAM",
165
+ code: "CONFIG_IMPORT_FAILED",
166
+ message: path.endsWith(".ts") || path.endsWith(".mts")
167
+ ? `${label} could not be imported; a TypeScript config file needs a runtime that strips types, or use tab.config.mjs`
168
+ : `${label} could not be imported`,
169
+ retryable: false,
170
+ details: { path },
171
+ cause: causeOf(error),
172
+ }));
173
+ }
174
+ function readDefaultExport(module, path) {
175
+ const exported = module["default"];
176
+ if (exported === undefined) {
177
+ return validationError("CONFIG_NO_DEFAULT_EXPORT", `\`${path}\` must default-export a config, for example \`export default defineTabConfig({ strategies: [] })\``, { details: { path } });
178
+ }
179
+ if (typeof exported !== "object" || exported === null) {
180
+ return validationError("CONFIG_INVALID", `the default export of \`${path}\` must be an object`, { details: { path } });
181
+ }
182
+ const candidate = exported;
183
+ if (candidate.x402 !== undefined && typeof candidate.x402 !== "function") {
184
+ return validationError("CONFIG_INVALID", `\`${path}\` declares \`x402\` but it is not a factory; it must be a function returning a signer or undefined, so the file holds no key`, { details: { path } });
185
+ }
186
+ if (candidate.strategies !== undefined && !Array.isArray(candidate.strategies)) {
187
+ return validationError("CONFIG_INVALID", `\`${path}\` declares \`strategies\` but it is not an array`, { details: { path } });
188
+ }
189
+ if (candidate.services !== undefined && !Array.isArray(candidate.services)) {
190
+ return validationError("CONFIG_INVALID", `\`${path}\` declares \`services\` but it is not an array`, { details: { path } });
191
+ }
192
+ return ok(exported);
193
+ }
194
+ async function resolveEntry(entry, index, configPath) {
195
+ const label = `strategies[${index}] of \`${configPath}\``;
196
+ if (typeof entry === "string") {
197
+ const module = await importSpecifier(entry, configPath);
198
+ if (!module.ok)
199
+ return module;
200
+ const exported = module.value["default"];
201
+ if (exported === undefined) {
202
+ return validationError("STRATEGY_MODULE_INVALID", `${label}: \`${entry}\` must default-export a PaymentStrategy or a factory returning one`, { details: { specifier: entry } });
203
+ }
204
+ return callIfFactory(exported, `${label} (\`${entry}\`)`);
205
+ }
206
+ return callIfFactory(entry, label);
207
+ }
208
+ /**
209
+ * A strategy is an object and a factory is a function, so `typeof` separates them.
210
+ *
211
+ * A factory returning `undefined` is passed straight back as `undefined` rather
212
+ * than sent to the validator, because declining is one of the two answers a
213
+ * factory is allowed to give. A bare `undefined` written directly in the array
214
+ * is still invalid, and still reaches the validator: that is a typo rather than
215
+ * a decision, and nothing about it says a key was missing.
216
+ */
217
+ async function callIfFactory(value, label) {
218
+ if (typeof value !== "function")
219
+ return validatePaymentStrategy(value, label);
220
+ const produced = await wrap(async () => (await value()), (error) => ({
221
+ category: "UPSTREAM",
222
+ code: "STRATEGY_FACTORY_FAILED",
223
+ message: `${label}: the strategy factory threw`,
224
+ retryable: false,
225
+ cause: causeOf(error),
226
+ }));
227
+ if (!produced.ok)
228
+ return produced;
229
+ if (produced.value === undefined || produced.value === null)
230
+ return ok(undefined);
231
+ return validatePaymentStrategy(produced.value, label);
232
+ }
233
+ /**
234
+ * Resolves a bare or relative specifier the way the consumer's own `import`
235
+ * would: from the config file. Falls back to a plain dynamic import, which covers
236
+ * a package the CommonJS resolver cannot see through its `exports` conditions.
237
+ */
238
+ async function importSpecifier(specifier, configPath) {
239
+ const fromConfig = wrapSync(() => createRequire(pathToFileURL(configPath)).resolve(specifier), (error) => ({
240
+ category: "NOT_FOUND",
241
+ code: "STRATEGY_MODULE_NOT_FOUND",
242
+ message: `\`${specifier}\` could not be resolved from \`${configPath}\``,
243
+ retryable: false,
244
+ details: { specifier, configPath },
245
+ cause: causeOf(error),
246
+ }));
247
+ if (fromConfig.ok) {
248
+ return importModule(fromConfig.value, `strategy module \`${specifier}\``);
249
+ }
250
+ return wrap(async () => (await import(specifier)), (error) => ({
251
+ category: "NOT_FOUND",
252
+ code: "STRATEGY_MODULE_NOT_FOUND",
253
+ message: `\`${specifier}\` could not be imported from \`${configPath}\` or resolved as a bare module`,
254
+ retryable: false,
255
+ details: { specifier, configPath },
256
+ cause: causeOf(error),
257
+ }));
258
+ }
259
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/payments/config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `tab.config.ts` discovery: mechanism three of R23.6.\n *\n * Zero-code wiring. A consumer writes a config file naming strategies as module\n * specifiers, and the strategies register themselves at startup with no\n * application code involved at all:\n *\n * ```ts\n * // tab.config.ts, at the consumer's project root\n * import { defineTabConfig } from \"@tabai/sdk\";\n * export default defineTabConfig({ strategies: [\"@acme/tab-strategy-solana\"] });\n * ```\n *\n * ## What an entry may be\n *\n * A module specifier, a strategy object, or a factory returning one. The\n * specifier form is the point of the mechanism; the other two exist because a\n * config file that can only name packages forces a consumer to publish one before\n * they can try anything.\n *\n * ## Where a specifier resolves from\n *\n * From the **config file**, not from this package. `@acme/tab-strategy-solana` is\n * the consumer's dependency and under pnpm it is not visible from inside\n * `@tabai/sdk` at all, so resolving relative to this module would fail for the\n * exact layout the workspace uses. `createRequire(configFileUrl)` resolves the\n * way the consumer's own `import` would, and a bare specifier that resolution\n * misses is retried as a plain dynamic import before the error is reported.\n *\n * ## The `.ts` config file and the host runtime\n *\n * This module imports the config file; it does not compile it. A `.ts` config\n * loads under a runtime that strips types, `tsx`, `node --experimental-strip-types`,\n * a bundler's dev server, and fails under one that does not. That failure comes\n * back as a `Result` naming the file and the requirement rather than as a stack\n * trace, and `tab.config.js` and `tab.config.mjs` are discovered too so a\n * consumer with a plain Node process has a first-class option.\n *\n * Requirements: 23.6, 21.5\n */\n\nimport { existsSync, statSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, isAbsolute, resolve as resolvePath } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { causeOf, ok, wrap, wrapSync, type Result } from \"../_shared/index.js\";\nimport { defaultLogger, type Logger } from \"../logger.js\";\nimport { notFoundError, validationError } from \"../errors.js\";\nimport { validatePaymentStrategy, type PaymentStrategy } from \"./strategy.js\";\nimport type { X402SignerFactory } from \"../x402/client.js\";\nimport {\n moduleStrategyRegistry,\n type StrategyRegistration,\n type StrategyRegistry,\n} from \"./registry.js\";\n\n/**\n * A factory in a config file, so a strategy that needs a signer can be built lazily.\n *\n * Returning `undefined` is a supported answer and means \"not available in this\n * environment\". That is what keeps every read on this rail keyless: the whole\n * point of a factory rather than an object is that a config file can declare a\n * strategy that only exists once a signing key does, and `tab_discover`,\n * `tab_status` and `doctor` never need one. A declining factory is skipped, and\n * the rest of the config - the Agent, the registry URL, the Service endpoints -\n * is kept.\n */\nexport type PaymentStrategyFactory = () =>\n | PaymentStrategy\n | undefined\n | Promise<PaymentStrategy | undefined>;\n\n/** A module specifier, a ready strategy, or a factory returning one. */\nexport type TabConfigStrategyEntry = string | PaymentStrategy | PaymentStrategyFactory;\n\n/**\n * One Service's off-chain coordinates.\n *\n * The chain records who operates a Service, what its tools cost and where it\n * collects Settlements. It records no URL, deliberately: an endpoint moves, and\n * a registry that pinned one would either go stale or need a write every time a\n * Service redeployed. So the endpoint is configuration, and this is where a\n * consumer states it.\n *\n * Without an entry here, `tab_discover` reports the Service with a null endpoint\n * and `tab_call` refuses it by name rather than inventing a URL.\n */\nexport interface TabServiceEntry {\n /** The Service's 32-byte registry key, as `tab_discover` reports it. */\n readonly serviceId: string;\n /** A label for a person. Defaults to the ascii the serviceId decodes to. */\n readonly name?: string;\n /** Absolute base URL `tab_call` sends requests to. */\n readonly endpoint: string;\n /**\n * The API Hub provider this Service fronts, if it fronts one.\n *\n * With this set, `tab_discover` fetches the provider's manifest and lists its\n * endpoints under the Service as the tools they are, each reachable through\n * the Service's `/hub/<prefix>` mount and metered onto the Agent's Open Tab.\n */\n readonly hub?: TabServiceHubEntry;\n /**\n * Headers sent with every call to this Service.\n *\n * A record for a Service that gates on something fixed, such as an API key. A\n * function for one that gates on something per request: the reference metering\n * gateway, for instance, requires a claim over the method, the path, the Agent\n * and the tool, which no static header can satisfy. Tab defines neither scheme\n * and validates neither -- this is the seam through which a Service's own\n * access control stays the Service's own.\n *\n * Never a Tab credential. The Tab identity headers are added by the 402 client\n * and nothing in Tab authenticates an Agent with a bearer token.\n */\n readonly headers?: Readonly<Record<string, string>> | ServiceHeaderProvider;\n}\n\n/** An API Hub provider fronted by a Service. See {@link TabServiceEntry.hub}. */\nexport interface TabServiceHubEntry {\n /** The Hub's provider slug, for example `weather-underground`. */\n readonly provider: string;\n /** The mount under the Service endpoint. Defaults to the provider slug, so `/hub/<provider>`. */\n readonly prefix?: string;\n /** Overrides the manifest URL, for a mirror or a test. */\n readonly manifestUrl?: string;\n}\n\n/** Builds the per-request headers one Service requires. See {@link TabServiceEntry.headers}. */\nexport type ServiceHeaderProvider = (\n request: ServiceHeaderRequest,\n) => Readonly<Record<string, string>> | Promise<Readonly<Record<string, string>>>;\n\n/** What the provider is told about the call it is producing headers for. */\nexport interface ServiceHeaderRequest {\n readonly method: string;\n /** The absolute URL the request is going to. */\n readonly url: string;\n /** The tool name as the caller gave it, before it is packed into a 32-byte key. */\n readonly tool: string;\n /** The Agent the call is metered against. */\n readonly agent: string;\n readonly serviceId: string;\n}\n\nexport interface TabConfig {\n readonly strategies?: readonly TabConfigStrategyEntry[];\n /**\n * The Agent's Monad address: whose Open Tab a metered call lands on.\n *\n * An address and never a key. Nothing in this package derives an address from\n * a private key, because doing so would mean a config file that holds one.\n */\n readonly agent?: string;\n /** Absolute base URL of the Tab registry read API, which serves discovery and status. */\n readonly registryUrl?: string;\n /** Where each Service can be reached. See {@link TabServiceEntry}. */\n readonly services?: readonly TabServiceEntry[];\n /**\n * The x402 signer, for the prepaid fallback.\n *\n * A factory and only a factory, for the reason `strategies` holds factories:\n * a signer is built from a key, and a config file must be loadable by the\n * three surfaces that hold none. Nothing calls this until a Service has\n * refused a call on credit and offered x402 for it, and a factory returning\n * `undefined` declines, which leaves that refusal the `LIMIT_EXCEEDED` it was.\n */\n readonly x402?: X402SignerFactory;\n}\n\n/**\n * Types a config file's default export. Identity at runtime, its whole job is to\n * make a typo in the config a compile error in the consumer's editor.\n */\nexport const defineTabConfig = (config: TabConfig): TabConfig => config;\n\n/**\n * The file names discovery looks for, in order. `.ts` first because it is the\n * documented form and the one that type-checks; the plain-JavaScript forms follow\n * so a consumer whose runtime strips no types is not shut out.\n */\nexport const TAB_CONFIG_FILE_NAMES = [\n \"tab.config.ts\",\n \"tab.config.mts\",\n \"tab.config.mjs\",\n \"tab.config.js\",\n \"tab.config.cjs\",\n] as const;\n\nexport interface FindTabConfigOptions {\n /** Where the walk starts. Defaults to the working directory. */\n readonly cwd?: string;\n readonly fileNames?: readonly string[];\n}\n\n/**\n * Walks from `cwd` towards the filesystem root and returns the first config file\n * found, or `undefined` when there is none.\n *\n * Absence is not an error: the whole point of the mechanism is that a consumer\n * who wants nothing from it writes nothing.\n */\nexport function findTabConfig(options: FindTabConfigOptions = {}): Result<string | undefined> {\n return wrapSync(\n () => {\n const fileNames = options.fileNames ?? TAB_CONFIG_FILE_NAMES;\n let directory = resolvePath(options.cwd ?? \".\");\n for (;;) {\n for (const fileName of fileNames) {\n const candidate = resolvePath(directory, fileName);\n if (existsSync(candidate) && statSync(candidate).isFile()) return candidate;\n }\n const parent = dirname(directory);\n if (parent === directory) return undefined;\n directory = parent;\n }\n },\n (error) => ({\n category: \"INTERNAL\",\n code: \"CONFIG_SEARCH_FAILED\",\n message: \"the tab.config search could not read the filesystem\",\n retryable: false,\n cause: causeOf(error),\n }),\n );\n}\n\nexport interface LoadTabConfigOptions extends FindTabConfigOptions {\n /** An explicit config file. Absolute, or relative to `cwd`. Missing is an error. */\n readonly configPath?: string;\n /**\n * Where the discovered strategies are registered. Omitted means the\n * module-level registry, which is what makes the mechanism zero-code; `false`\n * loads and validates without registering anything.\n */\n readonly registry?: StrategyRegistry | false;\n readonly logger?: Logger;\n}\n\nexport interface LoadedTabConfig {\n /** The file that was loaded, or `undefined` when none was found. */\n readonly path: string | undefined;\n readonly config: TabConfig;\n readonly strategies: readonly PaymentStrategy[];\n /** Empty when `registry` was `false`. */\n readonly registrations: readonly StrategyRegistration[];\n}\n\nconst EMPTY_CONFIG: TabConfig = {};\n\n/**\n * Loads a config file, resolves every strategy entry, and registers the result.\n *\n * Returns a `Result` for every failure, including a config file that throws on\n * import: a consumer's config is consumer code, and this package does not turn\n * their mistake into an unhandled rejection.\n */\nexport async function loadTabConfig(\n options: LoadTabConfigOptions = {},\n): Promise<Result<LoadedTabConfig>> {\n const logger = options.logger ?? defaultLogger;\n\n const located = locateConfig(options);\n if (!located.ok) return located;\n const path = located.value;\n\n if (path === undefined) {\n return ok({ path: undefined, config: EMPTY_CONFIG, strategies: [], registrations: [] });\n }\n\n const imported = await importModule(path, `tab config \\`${path}\\``);\n if (!imported.ok) return imported;\n\n const config = readDefaultExport(imported.value, path);\n if (!config.ok) return config;\n\n const strategies: PaymentStrategy[] = [];\n let declined = 0;\n for (const [index, entry] of (config.value.strategies ?? []).entries()) {\n const resolved = await resolveEntry(entry, index, path);\n if (!resolved.ok) return resolved;\n // `undefined` is the factory declining, not a fault. Skip it and keep going.\n if (resolved.value === undefined) {\n declined += 1;\n continue;\n }\n strategies.push(resolved.value);\n }\n\n const registrations: StrategyRegistration[] = [];\n if (options.registry !== false) {\n const registry = options.registry ?? moduleStrategyRegistry(logger);\n for (const strategy of strategies) {\n const outcome = registry.register(strategy);\n if (!outcome.ok) return outcome;\n registrations.push(outcome.value);\n }\n }\n\n logger.debug(\"tab config loaded\", { path, strategies: strategies.length, declined });\n return ok({ path, config: config.value, strategies, registrations });\n}\n\nfunction locateConfig(options: LoadTabConfigOptions): Result<string | undefined> {\n if (options.configPath === undefined) return findTabConfig(options);\n\n const cwd = resolvePath(options.cwd ?? \".\");\n const path = isAbsolute(options.configPath)\n ? options.configPath\n : resolvePath(cwd, options.configPath);\n if (!existsSync(path)) {\n return notFoundError(\"CONFIG_NOT_FOUND\", `no tab config file at \\`${path}\\``, {\n details: { path },\n });\n }\n return ok(path);\n}\n\n/** Imports a file by path. A `.ts` file needs a type-stripping runtime, so say so. */\nasync function importModule(path: string, label: string): Promise<Result<Record<string, unknown>>> {\n const href = pathToFileURL(path).href;\n return wrap(\n async () => (await import(href)) as Record<string, unknown>,\n (error) => ({\n category: \"UPSTREAM\",\n code: \"CONFIG_IMPORT_FAILED\",\n message: path.endsWith(\".ts\") || path.endsWith(\".mts\")\n ? `${label} could not be imported; a TypeScript config file needs a runtime that strips types, or use tab.config.mjs`\n : `${label} could not be imported`,\n retryable: false,\n details: { path },\n cause: causeOf(error),\n }),\n );\n}\n\nfunction readDefaultExport(module: Record<string, unknown>, path: string): Result<TabConfig> {\n const exported = module[\"default\"];\n if (exported === undefined) {\n return validationError(\n \"CONFIG_NO_DEFAULT_EXPORT\",\n `\\`${path}\\` must default-export a config, for example \\`export default defineTabConfig({ strategies: [] })\\``,\n { details: { path } },\n );\n }\n if (typeof exported !== \"object\" || exported === null) {\n return validationError(\n \"CONFIG_INVALID\",\n `the default export of \\`${path}\\` must be an object`,\n { details: { path } },\n );\n }\n const candidate = exported as { strategies?: unknown; services?: unknown; x402?: unknown };\n if (candidate.x402 !== undefined && typeof candidate.x402 !== \"function\") {\n return validationError(\n \"CONFIG_INVALID\",\n `\\`${path}\\` declares \\`x402\\` but it is not a factory; it must be a function returning a signer or undefined, so the file holds no key`,\n { details: { path } },\n );\n }\n if (candidate.strategies !== undefined && !Array.isArray(candidate.strategies)) {\n return validationError(\n \"CONFIG_INVALID\",\n `\\`${path}\\` declares \\`strategies\\` but it is not an array`,\n { details: { path } },\n );\n }\n if (candidate.services !== undefined && !Array.isArray(candidate.services)) {\n return validationError(\n \"CONFIG_INVALID\",\n `\\`${path}\\` declares \\`services\\` but it is not an array`,\n { details: { path } },\n );\n }\n return ok(exported as TabConfig);\n}\n\nasync function resolveEntry(\n entry: TabConfigStrategyEntry,\n index: number,\n configPath: string,\n): Promise<Result<PaymentStrategy | undefined>> {\n const label = `strategies[${index}] of \\`${configPath}\\``;\n\n if (typeof entry === \"string\") {\n const module = await importSpecifier(entry, configPath);\n if (!module.ok) return module;\n const exported = module.value[\"default\"];\n if (exported === undefined) {\n return validationError(\n \"STRATEGY_MODULE_INVALID\",\n `${label}: \\`${entry}\\` must default-export a PaymentStrategy or a factory returning one`,\n { details: { specifier: entry } },\n );\n }\n return callIfFactory(exported, `${label} (\\`${entry}\\`)`);\n }\n\n return callIfFactory(entry, label);\n}\n\n/**\n * A strategy is an object and a factory is a function, so `typeof` separates them.\n *\n * A factory returning `undefined` is passed straight back as `undefined` rather\n * than sent to the validator, because declining is one of the two answers a\n * factory is allowed to give. A bare `undefined` written directly in the array\n * is still invalid, and still reaches the validator: that is a typo rather than\n * a decision, and nothing about it says a key was missing.\n */\nasync function callIfFactory(\n value: unknown,\n label: string,\n): Promise<Result<PaymentStrategy | undefined>> {\n if (typeof value !== \"function\") return validatePaymentStrategy(value, label);\n\n const produced = await wrap(\n async () => (await (value as PaymentStrategyFactory)()) as unknown,\n (error) => ({\n category: \"UPSTREAM\",\n code: \"STRATEGY_FACTORY_FAILED\",\n message: `${label}: the strategy factory threw`,\n retryable: false,\n cause: causeOf(error),\n }),\n );\n if (!produced.ok) return produced;\n if (produced.value === undefined || produced.value === null) return ok(undefined);\n return validatePaymentStrategy(produced.value, label);\n}\n\n/**\n * Resolves a bare or relative specifier the way the consumer's own `import`\n * would: from the config file. Falls back to a plain dynamic import, which covers\n * a package the CommonJS resolver cannot see through its `exports` conditions.\n */\nasync function importSpecifier(\n specifier: string,\n configPath: string,\n): Promise<Result<Record<string, unknown>>> {\n const fromConfig = wrapSync(\n () => createRequire(pathToFileURL(configPath)).resolve(specifier),\n (error) => ({\n category: \"NOT_FOUND\",\n code: \"STRATEGY_MODULE_NOT_FOUND\",\n message: `\\`${specifier}\\` could not be resolved from \\`${configPath}\\``,\n retryable: false,\n details: { specifier, configPath },\n cause: causeOf(error),\n }),\n );\n\n if (fromConfig.ok) {\n return importModule(fromConfig.value, `strategy module \\`${specifier}\\``);\n }\n\n return wrap(\n async () => (await import(specifier)) as Record<string, unknown>,\n (error) => ({\n category: \"NOT_FOUND\",\n code: \"STRATEGY_MODULE_NOT_FOUND\",\n message: `\\`${specifier}\\` could not be imported from \\`${configPath}\\` or resolved as a bare module`,\n retryable: false,\n details: { specifier, configPath },\n cause: causeOf(error),\n }),\n );\n}\n"]}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The payment-strategy seam, assembled.
3
+ *
4
+ * Requirements: 23.1, 23.6, 23.7
5
+ */
6
+ export * from "./strategy.js";
7
+ export * from "./registry.js";
8
+ export * from "./config.js";
9
+ export * from "./abi.js";
10
+ export * from "./monad.js";
11
+ export * from "./kuru.js";
12
+ export * from "./permit2.js";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/payments/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The payment-strategy seam, assembled.
3
+ *
4
+ * Requirements: 23.1, 23.6, 23.7
5
+ */
6
+ export * from "./strategy.js";
7
+ export * from "./registry.js";
8
+ export * from "./config.js";
9
+ export * from "./abi.js";
10
+ export * from "./monad.js";
11
+ export * from "./kuru.js";
12
+ export * from "./permit2.js";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/payments/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC","sourcesContent":["/**\n * The payment-strategy seam, assembled.\n *\n * Requirements: 23.1, 23.6, 23.7\n */\n\nexport * from \"./strategy.js\";\nexport * from \"./registry.js\";\nexport * from \"./config.js\";\nexport * from \"./abi.js\";\nexport * from \"./monad.js\";\nexport * from \"./kuru.js\";\nexport * from \"./permit2.js\";\n"]}
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Settle in any asset through Kuru: a strategy that tops the Agent's balance of
3
+ * the Asset up from another token before delegating the Settlement.
4
+ *
5
+ * ## What it does
6
+ *
7
+ * `TabSettlement.settle` moves the Asset the tab is denominated in, and an
8
+ * Agent that holds MON, or a different stablecoin, cannot settle until it holds
9
+ * enough of that Asset. {@link createKuruFundedStrategy} wraps the Monad
10
+ * strategy: before every `settle` it reads the Agent's balance of the Asset,
11
+ * and when it is short, swaps the shortfall in from a configured source token
12
+ * through Kuru, Monad's on-chain order book, and only then settles. The
13
+ * Settlement itself is still the inner strategy's transaction, so the receipt,
14
+ * the `Settled` event and the atomic apply are unchanged.
15
+ *
16
+ * ## The swap is a seam
17
+ *
18
+ * The swap runs through a {@link KuruRouter}: `quote` says how much of the
19
+ * source token buys the shortfall, `swap` executes it. {@link createKuruOnchainRouter}
20
+ * is the shipped implementation over Kuru's `Router.anyToAnySwap`, which is
21
+ * the same entry point on Testnet and Mainnet, driven with a configured route
22
+ * of market addresses. A test hands in a fake router and exercises the whole
23
+ * decision without a chain.
24
+ *
25
+ * ## Why not Kuru's own SDK or its aggregator API
26
+ *
27
+ * `@kuru-labs/kuru-sdk` pins ethers 5 and takes swap amounts as floating
28
+ * point numbers, and the Kuru Flow aggregator API (`ws.kuru.io/api/quote`)
29
+ * needs a bearer token and returns a transaction in a shape the docs do not
30
+ * define. Amounts here are `bigint` base units end to end, so the router talks
31
+ * to the contract directly, with the amounts it was given.
32
+ *
33
+ * ## Amounts
34
+ *
35
+ * `amountOut` is the exact shortfall and is passed as the swap's minimum, so
36
+ * the Settlement is either fully funded or the swap reverts. `amountIn` is a
37
+ * ceiling: the on-chain router quotes by simulation at that ceiling, and the
38
+ * Agent's slippage tolerance sets how much above the quoted price it will pay.
39
+ * Anything the swap returns above the shortfall stays in the Agent's balance.
40
+ */
41
+ import { type Address, type Hex, type Result } from "../_shared/index.js";
42
+ import { type Logger } from "../logger.js";
43
+ import type { EthersV6Signer } from "./monad.js";
44
+ import { type AssetRef, type PaymentStrategy } from "./strategy.js";
45
+ /** The address Kuru's router reads as the native token, MON. */
46
+ export declare const KURU_NATIVE_TOKEN: Address;
47
+ /** Kuru's deployments, from its Contract Addresses page. The Router is what `anyToAnySwap` lives on. */
48
+ export declare const KURU_DEPLOYMENTS: {
49
+ readonly mainnet: {
50
+ readonly chainId: 143n;
51
+ readonly router: Address;
52
+ readonly marginAccount: Address;
53
+ /** The aggregator entry point. Mainnet only: the docs list none for Testnet. */
54
+ readonly flowEntrypoint: Address;
55
+ readonly wmon: Address;
56
+ readonly markets: {
57
+ readonly "MON-USDC": Address;
58
+ readonly "MON-AUSD": Address;
59
+ };
60
+ };
61
+ readonly testnet: {
62
+ readonly chainId: 10143n;
63
+ readonly router: Address;
64
+ readonly marginAccount: Address;
65
+ /** Kuru's own test USDC on Testnet, which is not Tab's `MockUsdc`. */
66
+ readonly usdc: Address;
67
+ };
68
+ };
69
+ /** The source token a swap draws from. `address` is {@link KURU_NATIVE_TOKEN} for MON. */
70
+ export interface KuruSourceToken {
71
+ readonly address: Address;
72
+ readonly decimals: number;
73
+ readonly symbol: string;
74
+ }
75
+ /** What the router is asked for. */
76
+ export interface KuruSwapRequest {
77
+ readonly chainId: bigint;
78
+ readonly tokenIn: Address;
79
+ readonly tokenOut: Address;
80
+ /** The exact shortfall in `tokenOut` base units. The swap must return at least this. */
81
+ readonly amountOut: bigint;
82
+ /** The most `tokenIn` the caller will spend. */
83
+ readonly maxAmountIn: bigint;
84
+ /** Where the output lands. The Agent, always. */
85
+ readonly recipient: Address;
86
+ }
87
+ export interface KuruQuote {
88
+ readonly request: KuruSwapRequest;
89
+ /** How much `tokenIn` the swap will be sent with. At most `request.maxAmountIn`. */
90
+ readonly amountIn: bigint;
91
+ /** What the router expects back. At least `request.amountOut`. */
92
+ readonly expectedOut: bigint;
93
+ }
94
+ export interface KuruSwapReceipt {
95
+ readonly txHash: Hex;
96
+ readonly amountIn: bigint;
97
+ /** What the swap returned, when the router could read it; the quote's expectation otherwise. */
98
+ readonly amountOut: bigint;
99
+ }
100
+ /** The swap seam. Both methods return a `Result`, never throw. */
101
+ export interface KuruRouter {
102
+ quote(request: KuruSwapRequest): Promise<Result<KuruQuote>>;
103
+ swap(quote: KuruQuote): Promise<Result<KuruSwapReceipt>>;
104
+ }
105
+ export interface KuruConfig {
106
+ readonly router: KuruRouter;
107
+ readonly source: KuruSourceToken;
108
+ /**
109
+ * Reads the Agent's balance of an Asset. Defaults to `balanceOf` through the
110
+ * inner signer's provider when `signer` is given; required otherwise.
111
+ */
112
+ readonly balanceOf?: (asset: AssetRef, owner: Address) => Promise<Result<bigint>>;
113
+ /** The most of the source token one Settlement may spend. Omitted sets no ceiling. */
114
+ readonly maxSourceAmount?: bigint;
115
+ /** Called with every swap that funded a Settlement. */
116
+ readonly onFunded?: (event: KuruFundingEvent) => void;
117
+ }
118
+ /** One top-up, as reported after the Settlement it funded. */
119
+ export interface KuruFundingEvent {
120
+ readonly agent: Address;
121
+ readonly asset: AssetRef;
122
+ readonly balanceBefore: bigint;
123
+ readonly shortfall: bigint;
124
+ readonly quote: KuruQuote;
125
+ readonly swap: KuruSwapReceipt;
126
+ }
127
+ export interface KuruFundedStrategyConfig {
128
+ /** The strategy that settles once the balance is there. The Monad strategy, ordinarily. */
129
+ readonly inner: PaymentStrategy;
130
+ readonly kuru: KuruConfig;
131
+ /**
132
+ * The Agent's signer, for the default `balanceOf`. Its `provider` is what the
133
+ * balance is read through. Not needed when `kuru.balanceOf` is supplied.
134
+ */
135
+ readonly signer?: EthersV6Signer;
136
+ readonly id?: string;
137
+ readonly logger?: Logger;
138
+ }
139
+ /**
140
+ * Builds the funded strategy. Construction is total.
141
+ *
142
+ * `supports`, `chainIds` and `quote` are the inner strategy's, so registering
143
+ * this in place of it changes nothing about which Assets resolve to it.
144
+ */
145
+ export declare function createKuruFundedStrategy(config: KuruFundedStrategyConfig): PaymentStrategy;
146
+ /** Kuru's `Router.anyToAnySwap`, the multi-hop swap entry point. */
147
+ export declare const KURU_ROUTER_ABI: readonly ["function anyToAnySwap(address[] _marketAddresses, bool[] _isBuy, bool[] _nativeSend, address _debitToken, address _creditToken, uint256 _amount, uint256 _minAmountOut) payable returns (uint256 _amountOut)"];
148
+ /**
149
+ * One route through Kuru's markets, as `anyToAnySwap` takes it.
150
+ *
151
+ * Every array is per hop. `isBuy` says whether the hop buys the market's base
152
+ * with its quote, `nativeSend` whether the hop is paid in MON. The MON-USDC
153
+ * market on Mainnet, selling MON for USDC, is one hop: `{ markets: [MON_USDC],
154
+ * isBuy: [false], nativeSend: [true] }`.
155
+ */
156
+ export interface KuruRoute {
157
+ readonly markets: readonly Address[];
158
+ readonly isBuy: readonly boolean[];
159
+ readonly nativeSend: readonly boolean[];
160
+ }
161
+ /** What the on-chain router needs of a signer: a call for the quote, a send for the swap. An `ethers.Signer` satisfies it. */
162
+ export type KuruSigner = EthersV6Signer;
163
+ export interface KuruOnchainRouterOptions {
164
+ readonly signer: KuruSigner;
165
+ /** Kuru's Router on the chain the signer is on. */
166
+ readonly router: Address;
167
+ /** Routes keyed by `${tokenIn}->${tokenOut}`, lower-cased. */
168
+ readonly routes: Readonly<Record<string, KuruRoute>>;
169
+ /** How far above the simulated price the swap may pay. Defaults to 100, one percent. */
170
+ readonly slippageBps?: number;
171
+ /**
172
+ * The `tokenIn` amount the price is probed at. Defaults to `maxAmountIn`.
173
+ * Probing at the size to be swapped keeps the quote honest about depth.
174
+ */
175
+ readonly probeAmountIn?: bigint;
176
+ readonly logger?: Logger;
177
+ }
178
+ /** The key `routes` is looked up by. */
179
+ export declare const kuruRouteKey: (tokenIn: string, tokenOut: string) => string;
180
+ /**
181
+ * A router over `anyToAnySwap`.
182
+ *
183
+ * Quoting is a simulation: the swap is `eth_call`ed at a probe size, the
184
+ * price it implies is scaled to the shortfall, and the slippage margin is
185
+ * added. Two probes at most, the second at the computed size, so the quote is
186
+ * checked at the amount that will be sent. The swap is then sent with the
187
+ * shortfall as `_minAmountOut`, which is what makes over-quoting harmless and
188
+ * under-quoting a revert rather than a short Settlement.
189
+ */
190
+ export declare function createKuruOnchainRouter(options: KuruOnchainRouterOptions): KuruRouter;
191
+ //# sourceMappingURL=kuru.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kuru.d.ts","sourceRoot":"","sources":["../../src/payments/kuru.ts"],"names":[],"mappings":"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"}