@capxul/sdk 1.0.0-alpha.9 → 1.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 (32) hide show
  1. package/README.md +121 -6
  2. package/dist/{InMemoryAuthCacheAdapter-v5W-XB5M.mjs → InMemoryAuthCacheAdapter-Dr1sEd9y.mjs} +36 -16
  3. package/dist/InMemoryAuthCacheAdapter-Dr1sEd9y.mjs.map +1 -0
  4. package/dist/create-capxul-client-C7H5b68l.d.mts +2764 -0
  5. package/dist/create-capxul-client-C7H5b68l.d.mts.map +1 -0
  6. package/dist/create-capxul-client-DiqVIxsV.mjs +6980 -0
  7. package/dist/create-capxul-client-DiqVIxsV.mjs.map +1 -0
  8. package/dist/index.d.mts +119 -2020
  9. package/dist/index.d.mts.map +1 -1
  10. package/dist/index.mjs +2464 -6308
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/node/index.d.mts +3 -6
  13. package/dist/node/index.d.mts.map +1 -1
  14. package/dist/node/index.mjs +27 -27
  15. package/dist/node/index.mjs.map +1 -1
  16. package/dist/signer-CJT0pPiO.d.mts +301 -0
  17. package/dist/signer-CJT0pPiO.d.mts.map +1 -0
  18. package/dist/testing/index.d.mts +54 -0
  19. package/dist/testing/index.d.mts.map +1 -0
  20. package/dist/testing/index.mjs +1068 -0
  21. package/dist/testing/index.mjs.map +1 -0
  22. package/package.json +17 -18
  23. package/dist/InMemoryAuthCacheAdapter-v5W-XB5M.mjs.map +0 -1
  24. package/dist/index-CTXgQ_xR.d.mts +0 -158
  25. package/dist/index-CTXgQ_xR.d.mts.map +0 -1
  26. package/dist/ports/safe-deployment.d.mts +0 -2
  27. package/dist/ports/safe-deployment.mjs +0 -38
  28. package/dist/ports/safe-deployment.mjs.map +0 -1
  29. package/dist/safe-deployment-D3k9yndM.d.mts +0 -136
  30. package/dist/safe-deployment-D3k9yndM.d.mts.map +0 -1
  31. package/dist/signer-DqDtJU1l.d.mts +0 -145
  32. package/dist/signer-DqDtJU1l.d.mts.map +0 -1
@@ -1,12 +1,9 @@
1
- import { s as AuthSession } from "../index-CTXgQ_xR.mjs";
2
- import { _ as CachedJwt, g as AuthCachePortTag, h as AuthCachePort, m as AuthCacheError, t as CapxulSigner } from "../signer-DqDtJU1l.mjs";
1
+ import { T as AuthSession, _ as AuthCachePortTag, g as AuthCachePort, h as AuthCacheError, n as CapxulSigner, v as CachedJwt } from "../signer-CJT0pPiO.mjs";
3
2
  import { Hex } from "viem";
4
- import { Effect, Layer } from "effect";
5
- import * as PlatformFileSystem from "@effect/platform/FileSystem";
6
- import * as PlatformPath from "@effect/platform/Path";
3
+ import { Effect, FileSystem, Layer, Path } from "effect";
7
4
 
8
5
  //#region src/adapters/auth-cache/FileSystemAuthCacheAdapter.d.ts
9
- type FileSystemRuntime = PlatformFileSystem.FileSystem | PlatformPath.Path;
6
+ type FileSystemRuntime = FileSystem.FileSystem | Path.Path;
10
7
  declare class FileSystemAuthCacheAdapter implements AuthCachePort {
11
8
  private readonly path;
12
9
  private readonly runtime;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/adapters/auth-cache/FileSystemAuthCacheAdapter.ts","../../src/node/index.ts"],"mappings":";;;;;;;;KAqBK,iBAAA,GAAoB,kBAAA,CAAmB,UAAA,GAAa,YAAA,CAAa,IAAI;AAAA,cAQ7D,0BAAA,YAAsC,aAAA;EAAA,iBAChC,IAAA;EAAA,iBACA,OAAA;EAAA,SACR,UAAA,EAAY,MAAA,CAAO,MAAA,CAAO,WAAA,SAAoB,cAAA;EAAA,SAC9C,UAAA,GAAa,OAAA,EAAS,WAAA,KAAgB,MAAA,CAAO,MAAA,OAAa,cAAA;EAAA,SAC1D,YAAA,EAAc,MAAA,CAAO,MAAA,OAAa,cAAA;EAAA,SAClC,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,SAAA,SAAkB,cAAA;EAAA,SACxC,MAAA,GAAS,GAAA,EAAK,SAAA,KAAc,MAAA,CAAO,MAAA,OAAa,cAAA;EAAA,SAChD,QAAA,EAAU,MAAA,CAAO,MAAA,OAAa,cAAA;cAE3B,IAAA,UAAc,OAAA,GAAS,KAAA,CAAM,KAAA,CAAM,iBAAA;EAAA,QAyCvC,IAAA;EAAA,QAyBA,KAAA;EAAA,QAgBA,GAAA;AAAA;AAAA,iBAWM,wBAAA,CAAyB,KAAA;EAAA,SAC9B,IAAA;EAAA,SACA,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,iBAAA;AAAA,IAC7B,KAAA,CAAM,KAAA,CAAM,gBAAA,EAAkB,cAAA;;;UC9GjB,iCAAA;EAAA,SACN,aAAA;EAAA,SACA,oBAAoB;AAAA;ADdC;;;;;AAAA,iBCsBhB,qBAAA,CAAsB,KAAA;EAAA,SAAkB,UAAA,EAAY,GAAA;AAAA,IAAQ,YAAY;;ADdd;AAQ1E;;;;;;;;iBC+BgB,0BAAA,CACd,OAAA,GAAS,iCAAA,GACR,aAAa"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/adapters/auth-cache/FileSystemAuthCacheAdapter.ts","../../src/node/index.ts"],"mappings":";;;;;KAwBK,iBAAA,GAAoB,UAAA,CAAmB,UAAA,GAAa,IAAA,CAAa,IAAI;AAAA,cAQ7D,0BAAA,YAAsC,aAAA;EAAA,iBAChC,IAAA;EAAA,iBACA,OAAA;EAAA,SACR,UAAA,EAAY,MAAA,CAAO,MAAA,CAAO,WAAA,SAAoB,cAAA;EAAA,SAC9C,UAAA,GAAa,OAAA,EAAS,WAAA,KAAgB,MAAA,CAAO,MAAA,OAAa,cAAA;EAAA,SAC1D,YAAA,EAAc,MAAA,CAAO,MAAA,OAAa,cAAA;EAAA,SAClC,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,SAAA,SAAkB,cAAA;EAAA,SACxC,MAAA,GAAS,GAAA,EAAK,SAAA,KAAc,MAAA,CAAO,MAAA,OAAa,cAAA;EAAA,SAChD,QAAA,EAAU,MAAA,CAAO,MAAA,OAAa,cAAA;cAE3B,IAAA,UAAc,OAAA,GAAS,KAAA,CAAM,KAAA,CAAM,iBAAA;EAAA,QA0CvC,IAAA;EAAA,QA0BA,KAAA;EAAA,QAiBA,GAAA;AAAA;AAAA,iBAWM,wBAAA,CAAyB,KAAA;EAAA,SAC9B,IAAA;EAAA,SACA,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,iBAAA;AAAA,IAC7B,KAAA,CAAM,KAAA,CAAM,gBAAA,EAAkB,cAAA;;;UCpHjB,iCAAA;EAAA,SACN,aAAA;EAAA,SACA,oBAAoB;AAAA;;;;;;iBAQf,qBAAA,CAAsB,KAAA;EAAA,SAAkB,UAAA,EAAY,GAAA;AAAA,IAAQ,YAAY;;;;;;;;;;;iBAyBxE,0BAAA,CACd,OAAA,GAAS,iCAAA,GACR,aAAa"}
@@ -1,12 +1,9 @@
1
- import { a as AuthCacheError, f as toAddress, i as parseCachedJwt, n as BrowserAuthCacheAdapter, o as AuthCachePortTag, r as parseAuthSession, t as InMemoryAuthCacheAdapter } from "../InMemoryAuthCacheAdapter-v5W-XB5M.mjs";
2
- import { Effect, Layer } from "effect";
1
+ import { a as AuthCacheError, f as toAddress, i as parseCachedJwt, n as BrowserAuthCacheAdapter, o as AuthCachePortTag, r as parseAuthSession, t as InMemoryAuthCacheAdapter } from "../InMemoryAuthCacheAdapter-Dr1sEd9y.mjs";
2
+ import { Effect, FileSystem, Layer, Path } from "effect";
3
3
  import { privateKeyToAccount } from "viem/accounts";
4
4
  import * as os from "node:os";
5
5
  import { join } from "node:path";
6
- import * as PlatformFileSystem from "@effect/platform/FileSystem";
7
- import * as PlatformPath from "@effect/platform/Path";
8
- import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem";
9
- import * as NodePath from "@effect/platform-node/NodePath";
6
+ import { NodeFileSystem, NodePath } from "@effect/platform-node";
10
7
  //#region src/adapters/auth-cache/FileSystemAuthCacheAdapter.ts
11
8
  function emptyPayload() {
12
9
  return {
@@ -27,42 +24,44 @@ var FileSystemAuthCacheAdapter = class {
27
24
  constructor(path, runtime = nodeFileSystemRuntime) {
28
25
  this.path = path;
29
26
  this.runtime = runtime;
27
+ const self = this;
30
28
  this.getSession = this.run("getSession", this.read().pipe(Effect.map((payload) => payload.session)));
31
- this.setSession = (session) => this.run("setSession", Effect.gen(this, function* () {
32
- const cur = yield* this.read();
33
- yield* this.write({
29
+ this.setSession = (session) => this.run("setSession", Effect.gen(function* () {
30
+ const cur = yield* self.read();
31
+ yield* self.write({
34
32
  session,
35
33
  jwt: cur.jwt
36
34
  });
37
35
  }));
38
- this.clearSession = this.run("clearSession", Effect.gen(this, function* () {
39
- const cur = yield* this.read();
40
- yield* this.write({
36
+ this.clearSession = this.run("clearSession", Effect.gen(function* () {
37
+ const cur = yield* self.read();
38
+ yield* self.write({
41
39
  session: null,
42
40
  jwt: cur.jwt
43
41
  });
44
42
  }));
45
43
  this.getJwt = this.run("getJwt", this.read().pipe(Effect.map((payload) => payload.jwt)));
46
- this.setJwt = (jwt) => this.run("setJwt", Effect.gen(this, function* () {
47
- const cur = yield* this.read();
48
- yield* this.write({
44
+ this.setJwt = (jwt) => this.run("setJwt", Effect.gen(function* () {
45
+ const cur = yield* self.read();
46
+ yield* self.write({
49
47
  session: cur.session,
50
48
  jwt
51
49
  });
52
50
  }));
53
- this.clearJwt = this.run("clearJwt", Effect.gen(this, function* () {
54
- const cur = yield* this.read();
55
- yield* this.write({
51
+ this.clearJwt = this.run("clearJwt", Effect.gen(function* () {
52
+ const cur = yield* self.read();
53
+ yield* self.write({
56
54
  session: cur.session,
57
55
  jwt: null
58
56
  });
59
57
  }));
60
58
  }
61
59
  read() {
62
- return Effect.gen(this, function* () {
63
- const fs = yield* PlatformFileSystem.FileSystem;
64
- if (!(yield* fs.exists(this.path))) return emptyPayload();
65
- const raw = yield* fs.readFileString(this.path, "utf-8");
60
+ const self = this;
61
+ return Effect.gen(function* () {
62
+ const fs = yield* FileSystem.FileSystem;
63
+ if (!(yield* fs.exists(self.path))) return emptyPayload();
64
+ const raw = yield* fs.readFileString(self.path, "utf-8");
66
65
  let parsed;
67
66
  try {
68
67
  parsed = JSON.parse(raw);
@@ -78,15 +77,16 @@ var FileSystemAuthCacheAdapter = class {
78
77
  });
79
78
  }
80
79
  write(payload) {
81
- return Effect.gen(this, function* () {
82
- const fs = yield* PlatformFileSystem.FileSystem;
83
- const dir = (yield* PlatformPath.Path).dirname(this.path);
80
+ const self = this;
81
+ return Effect.gen(function* () {
82
+ const fs = yield* FileSystem.FileSystem;
83
+ const dir = (yield* Path.Path).dirname(self.path);
84
84
  if (!(yield* fs.exists(dir))) yield* fs.makeDirectory(dir, {
85
85
  recursive: true,
86
86
  mode: 448
87
87
  });
88
- yield* fs.writeFileString(this.path, JSON.stringify(payload), { mode: 384 });
89
- yield* fs.chmod(this.path, 384);
88
+ yield* fs.writeFileString(self.path, JSON.stringify(payload), { mode: 384 });
89
+ yield* fs.chmod(self.path, 384);
90
90
  });
91
91
  }
92
92
  run(operation, effect) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/adapters/auth-cache/FileSystemAuthCacheAdapter.ts","../../src/node/index.ts"],"sourcesContent":["import type * as PlatformError from \"@effect/platform/Error\";\nimport * as PlatformFileSystem from \"@effect/platform/FileSystem\";\nimport * as PlatformPath from \"@effect/platform/Path\";\nimport * as NodeFileSystem from \"@effect/platform-node/NodeFileSystem\";\nimport * as NodePath from \"@effect/platform-node/NodePath\";\nimport { Effect, Layer } from \"effect\";\nimport type { AuthSession } from \"@capxul/types\";\n\nimport {\n AuthCacheError,\n AuthCachePortTag,\n type AuthCachePort,\n type CachedJwt,\n} from \"../../ports/auth-cache\";\nimport { parseAuthSession, parseCachedJwt } from \"./serialization\";\n\ninterface FilePayload {\n readonly session: AuthSession | null;\n readonly jwt: CachedJwt | null;\n}\n\ntype FileSystemRuntime = PlatformFileSystem.FileSystem | PlatformPath.Path;\n\nfunction emptyPayload(): FilePayload {\n return { session: null, jwt: null };\n}\n\nconst nodeFileSystemRuntime = Layer.merge(NodeFileSystem.layer, NodePath.layer);\n\nexport class FileSystemAuthCacheAdapter implements AuthCachePort {\n private readonly path: string;\n private readonly runtime: Layer.Layer<FileSystemRuntime>;\n readonly getSession: Effect.Effect<AuthSession | null, AuthCacheError>;\n readonly setSession: (session: AuthSession) => Effect.Effect<void, AuthCacheError>;\n readonly clearSession: Effect.Effect<void, AuthCacheError>;\n readonly getJwt: Effect.Effect<CachedJwt | null, AuthCacheError>;\n readonly setJwt: (jwt: CachedJwt) => Effect.Effect<void, AuthCacheError>;\n readonly clearJwt: Effect.Effect<void, AuthCacheError>;\n\n constructor(path: string, runtime: Layer.Layer<FileSystemRuntime> = nodeFileSystemRuntime) {\n this.path = path;\n this.runtime = runtime;\n\n this.getSession = this.run(\n \"getSession\",\n this.read().pipe(Effect.map((payload) => payload.session)),\n );\n this.setSession = (session: AuthSession) =>\n this.run(\n \"setSession\",\n Effect.gen(this, function* () {\n const cur = yield* this.read();\n yield* this.write({ session, jwt: cur.jwt });\n }),\n );\n this.clearSession = this.run(\n \"clearSession\",\n Effect.gen(this, function* () {\n const cur = yield* this.read();\n yield* this.write({ session: null, jwt: cur.jwt });\n }),\n );\n this.getJwt = this.run(\"getJwt\", this.read().pipe(Effect.map((payload) => payload.jwt)));\n this.setJwt = (jwt: CachedJwt) =>\n this.run(\n \"setJwt\",\n Effect.gen(this, function* () {\n const cur = yield* this.read();\n yield* this.write({ session: cur.session, jwt });\n }),\n );\n this.clearJwt = this.run(\n \"clearJwt\",\n Effect.gen(this, function* () {\n const cur = yield* this.read();\n yield* this.write({ session: cur.session, jwt: null });\n }),\n );\n }\n\n private read(): Effect.Effect<FilePayload, PlatformError.PlatformError, FileSystemRuntime> {\n return Effect.gen(this, function* () {\n const fs = yield* PlatformFileSystem.FileSystem;\n const exists = yield* fs.exists(this.path);\n if (!exists) return emptyPayload();\n const raw = yield* fs.readFileString(this.path, \"utf-8\");\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return emptyPayload();\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return emptyPayload();\n }\n const payload = parsed as { readonly session?: unknown; readonly jwt?: unknown };\n\n return {\n session: parseAuthSession(payload.session),\n jwt: parseCachedJwt(payload.jwt),\n };\n });\n }\n\n private write(\n payload: FilePayload,\n ): Effect.Effect<void, PlatformError.PlatformError, FileSystemRuntime> {\n return Effect.gen(this, function* () {\n const fs = yield* PlatformFileSystem.FileSystem;\n const path = yield* PlatformPath.Path;\n const dir = path.dirname(this.path);\n const dirExists = yield* fs.exists(dir);\n if (!dirExists) {\n yield* fs.makeDirectory(dir, { recursive: true, mode: 0o700 });\n }\n yield* fs.writeFileString(this.path, JSON.stringify(payload), { mode: 0o600 });\n yield* fs.chmod(this.path, 0o600);\n });\n }\n\n private run<T>(\n operation: string,\n effect: Effect.Effect<T, PlatformError.PlatformError, FileSystemRuntime>,\n ): Effect.Effect<T, AuthCacheError> {\n return effect.pipe(\n Effect.mapError((cause) => toAuthCacheError(operation, cause)),\n Effect.provide(this.runtime),\n );\n }\n}\n\nexport function FileSystemAuthCacheLayer(input: {\n readonly path: string;\n readonly runtime?: Layer.Layer<FileSystemRuntime>;\n}): Layer.Layer<AuthCachePortTag, AuthCacheError> {\n return Layer.effect(\n AuthCachePortTag,\n Effect.sync(() => new FileSystemAuthCacheAdapter(input.path, input.runtime)).pipe(\n Effect.mapError((cause) => toAuthCacheError(\"initialize\", cause)),\n ),\n );\n}\n\nfunction toAuthCacheError(operation: string, cause: unknown): AuthCacheError {\n return new AuthCacheError({ operation, cause });\n}\n","// `@capxul/sdk/node` — node-only entry (published-package-boundaries.md).\n//\n// The default `@capxul/sdk` entry is browser-clean: it never statically reaches\n// `@effect/platform-node`. Node consumers import the on-disk auth cache and the\n// node key `CapxulSigner` from here.\n\nimport * as os from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { toAddress } from \"@capxul/types\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport type { Hex } from \"viem\";\n\nimport { BrowserAuthCacheAdapter } from \"../adapters/auth-cache/BrowserAuthCacheAdapter\";\nimport { FileSystemAuthCacheAdapter } from \"../adapters/auth-cache/FileSystemAuthCacheAdapter\";\nimport { InMemoryAuthCacheAdapter } from \"../adapters/auth-cache/InMemoryAuthCacheAdapter\";\nimport type { WindowLike } from \"../client/window-like\";\nimport type { AuthCachePort } from \"../ports/auth-cache\";\nimport type { CapxulSigner } from \"../signer\";\n\nexport {\n FileSystemAuthCacheAdapter,\n FileSystemAuthCacheLayer,\n} from \"../adapters/auth-cache/FileSystemAuthCacheAdapter\";\n\nexport interface DetectNodeAuthCacheAdapterOptions {\n readonly authCachePath?: string;\n readonly resolveHomeDirectory?: () => string;\n}\n\n/**\n * Node `CapxulSigner` backed by a raw private key. Signs the EIP-712 `SafeOp`\n * digest the backend returns for a prepared deployment UserOperation. The\n * reference CLI builds this from `DEPLOYER_PRIVATE_KEY` for the live capstone.\n */\nexport function localPrivateKeySigner(input: { readonly privateKey: Hex }): CapxulSigner {\n const account = privateKeyToAccount(input.privateKey);\n return {\n source: \"local-private-key\",\n async getAddress() {\n return toAddress(account.address);\n },\n async signUserOpHash(hash: Hex): Promise<Hex> {\n // `sign({ hash })` signs the already-computed SafeOp digest directly.\n // `signMessage({ message: { raw: hash } })` would add an EIP-191 prefix.\n return account.sign({ hash });\n },\n };\n}\n\n/**\n * Node-aware auth-cache detection. Mirrors the historic default order:\n * 1. Browser localStorage → BrowserAuthCacheAdapter\n * 2. Node.js process → FileSystemAuthCacheAdapter\n * (`~/.config/capxul/auth-cache.json`)\n * 3. Neither detected → InMemoryAuthCacheAdapter\n *\n * Use this from a Node entrypoint and pass the result to\n * `createCapxulClient({ authCache })` for on-disk session persistence.\n */\nexport function detectNodeAuthCacheAdapter(\n options: DetectNodeAuthCacheAdapterOptions = {},\n): AuthCachePort {\n const globalAny = globalThis as unknown as {\n readonly window?: WindowLike;\n readonly process?: { readonly versions?: { readonly node?: string } };\n };\n if (globalAny.window?.localStorage !== undefined) {\n return new BrowserAuthCacheAdapter(globalAny.window.localStorage);\n }\n if (globalAny.process?.versions?.node !== undefined) {\n const authCachePath =\n normalizeConfiguredAuthCachePath(options.authCachePath) ??\n resolveDefaultAuthCachePath(options.resolveHomeDirectory ?? os.homedir);\n if (authCachePath !== null) return new FileSystemAuthCacheAdapter(authCachePath);\n }\n return new InMemoryAuthCacheAdapter();\n}\n\nfunction normalizeConfiguredAuthCachePath(path: string | undefined): string | null {\n if (path === undefined) return null;\n const trimmed = path.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction resolveDefaultAuthCachePath(resolveHomeDirectory: () => string): string | null {\n try {\n return join(resolveHomeDirectory(), \".config\", \"capxul\", \"auth-cache.json\");\n } catch {\n return null;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["PlatformFileSystem","PlatformPath"],"sources":["../../src/adapters/auth-cache/FileSystemAuthCacheAdapter.ts","../../src/node/index.ts"],"sourcesContent":["/* oxlint-disable typescript/no-this-alias -- Effect.gen callbacks are generator functions, so adapter receivers are captured explicitly. */\nimport { NodeFileSystem, NodePath } from \"@effect/platform-node\";\nimport {\n Effect,\n FileSystem as PlatformFileSystem,\n Layer,\n Path as PlatformPath,\n PlatformError,\n} from \"effect\";\nimport type { AuthSession } from \"@capxul/types\";\n\nimport {\n AuthCacheError,\n AuthCachePortTag,\n type AuthCachePort,\n type CachedJwt,\n} from \"../../ports/auth-cache\";\nimport { parseAuthSession, parseCachedJwt } from \"./serialization\";\n\ninterface FilePayload {\n readonly session: AuthSession | null;\n readonly jwt: CachedJwt | null;\n}\n\ntype FileSystemRuntime = PlatformFileSystem.FileSystem | PlatformPath.Path;\n\nfunction emptyPayload(): FilePayload {\n return { session: null, jwt: null };\n}\n\nconst nodeFileSystemRuntime = Layer.merge(NodeFileSystem.layer, NodePath.layer);\n\nexport class FileSystemAuthCacheAdapter implements AuthCachePort {\n private readonly path: string;\n private readonly runtime: Layer.Layer<FileSystemRuntime>;\n readonly getSession: Effect.Effect<AuthSession | null, AuthCacheError>;\n readonly setSession: (session: AuthSession) => Effect.Effect<void, AuthCacheError>;\n readonly clearSession: Effect.Effect<void, AuthCacheError>;\n readonly getJwt: Effect.Effect<CachedJwt | null, AuthCacheError>;\n readonly setJwt: (jwt: CachedJwt) => Effect.Effect<void, AuthCacheError>;\n readonly clearJwt: Effect.Effect<void, AuthCacheError>;\n\n constructor(path: string, runtime: Layer.Layer<FileSystemRuntime> = nodeFileSystemRuntime) {\n this.path = path;\n this.runtime = runtime;\n const self = this;\n\n this.getSession = this.run(\n \"getSession\",\n this.read().pipe(Effect.map((payload) => payload.session)),\n );\n this.setSession = (session: AuthSession) =>\n this.run(\n \"setSession\",\n Effect.gen(function* () {\n const cur = yield* self.read();\n yield* self.write({ session, jwt: cur.jwt });\n }),\n );\n this.clearSession = this.run(\n \"clearSession\",\n Effect.gen(function* () {\n const cur = yield* self.read();\n yield* self.write({ session: null, jwt: cur.jwt });\n }),\n );\n this.getJwt = this.run(\"getJwt\", this.read().pipe(Effect.map((payload) => payload.jwt)));\n this.setJwt = (jwt: CachedJwt) =>\n this.run(\n \"setJwt\",\n Effect.gen(function* () {\n const cur = yield* self.read();\n yield* self.write({ session: cur.session, jwt });\n }),\n );\n this.clearJwt = this.run(\n \"clearJwt\",\n Effect.gen(function* () {\n const cur = yield* self.read();\n yield* self.write({ session: cur.session, jwt: null });\n }),\n );\n }\n\n private read(): Effect.Effect<FilePayload, PlatformError.PlatformError, FileSystemRuntime> {\n const self = this;\n return Effect.gen(function* () {\n const fs = yield* PlatformFileSystem.FileSystem;\n const exists = yield* fs.exists(self.path);\n if (!exists) return emptyPayload();\n const raw = yield* fs.readFileString(self.path, \"utf-8\");\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return emptyPayload();\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return emptyPayload();\n }\n const payload = parsed as { readonly session?: unknown; readonly jwt?: unknown };\n\n return {\n session: parseAuthSession(payload.session),\n jwt: parseCachedJwt(payload.jwt),\n };\n });\n }\n\n private write(\n payload: FilePayload,\n ): Effect.Effect<void, PlatformError.PlatformError, FileSystemRuntime> {\n const self = this;\n return Effect.gen(function* () {\n const fs = yield* PlatformFileSystem.FileSystem;\n const path = yield* PlatformPath.Path;\n const dir = path.dirname(self.path);\n const dirExists = yield* fs.exists(dir);\n if (!dirExists) {\n yield* fs.makeDirectory(dir, { recursive: true, mode: 0o700 });\n }\n yield* fs.writeFileString(self.path, JSON.stringify(payload), { mode: 0o600 });\n yield* fs.chmod(self.path, 0o600);\n });\n }\n\n private run<T>(\n operation: string,\n effect: Effect.Effect<T, PlatformError.PlatformError, FileSystemRuntime>,\n ): Effect.Effect<T, AuthCacheError> {\n return effect.pipe(\n Effect.mapError((cause) => toAuthCacheError(operation, cause)),\n Effect.provide(this.runtime),\n );\n }\n}\n\nexport function FileSystemAuthCacheLayer(input: {\n readonly path: string;\n readonly runtime?: Layer.Layer<FileSystemRuntime>;\n}): Layer.Layer<AuthCachePortTag, AuthCacheError> {\n return Layer.effect(\n AuthCachePortTag,\n Effect.sync(() => new FileSystemAuthCacheAdapter(input.path, input.runtime)).pipe(\n Effect.mapError((cause) => toAuthCacheError(\"initialize\", cause)),\n ),\n );\n}\n\nfunction toAuthCacheError(operation: string, cause: unknown): AuthCacheError {\n return new AuthCacheError({ operation, cause });\n}\n","// `@capxul/sdk/node` — node-only entry (published-package-boundaries.md).\n//\n// The default `@capxul/sdk` entry is browser-clean: it never statically reaches\n// `@effect/platform-node`. Node consumers import the on-disk auth cache and the\n// node key `CapxulSigner` from here.\n\nimport * as os from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { toAddress } from \"@capxul/types\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport type { Hex } from \"viem\";\n\nimport { BrowserAuthCacheAdapter } from \"../adapters/auth-cache/BrowserAuthCacheAdapter\";\nimport { FileSystemAuthCacheAdapter } from \"../adapters/auth-cache/FileSystemAuthCacheAdapter\";\nimport { InMemoryAuthCacheAdapter } from \"../adapters/auth-cache/InMemoryAuthCacheAdapter\";\nimport type { WindowLike } from \"../surface/window-like\";\nimport type { AuthCachePort } from \"../ports/auth-cache\";\nimport type { CapxulSigner } from \"../signer\";\n\nexport {\n FileSystemAuthCacheAdapter,\n FileSystemAuthCacheLayer,\n} from \"../adapters/auth-cache/FileSystemAuthCacheAdapter\";\n\nexport interface DetectNodeAuthCacheAdapterOptions {\n readonly authCachePath?: string;\n readonly resolveHomeDirectory?: () => string;\n}\n\n/**\n * Node `CapxulSigner` backed by a raw private key. Signs the EIP-712 `SafeOp`\n * digest the backend returns for a prepared deployment UserOperation. The\n * reference CLI builds this from `DEPLOYER_PRIVATE_KEY` for the live capstone.\n */\nexport function localPrivateKeySigner(input: { readonly privateKey: Hex }): CapxulSigner {\n const account = privateKeyToAccount(input.privateKey);\n return {\n source: \"local-private-key\",\n async getAddress() {\n return toAddress(account.address);\n },\n async signUserOpHash(hash: Hex): Promise<Hex> {\n // `sign({ hash })` signs the already-computed SafeOp digest directly.\n // `signMessage({ message: { raw: hash } })` would add an EIP-191 prefix.\n return account.sign({ hash });\n },\n };\n}\n\n/**\n * Node-aware auth-cache detection. Mirrors the historic default order:\n * 1. Browser localStorage → BrowserAuthCacheAdapter\n * 2. Node.js process → FileSystemAuthCacheAdapter\n * (`~/.config/capxul/auth-cache.json`)\n * 3. Neither detected → InMemoryAuthCacheAdapter\n *\n * Use this from a Node entrypoint and pass the result to\n * `createCapxulClient({ authCache })` for on-disk session persistence.\n */\nexport function detectNodeAuthCacheAdapter(\n options: DetectNodeAuthCacheAdapterOptions = {},\n): AuthCachePort {\n const globalAny = globalThis as unknown as {\n readonly window?: WindowLike;\n readonly process?: { readonly versions?: { readonly node?: string } };\n };\n if (globalAny.window?.localStorage !== undefined) {\n return new BrowserAuthCacheAdapter(globalAny.window.localStorage);\n }\n if (globalAny.process?.versions?.node !== undefined) {\n const authCachePath =\n normalizeConfiguredAuthCachePath(options.authCachePath) ??\n resolveDefaultAuthCachePath(options.resolveHomeDirectory ?? os.homedir);\n if (authCachePath !== null) return new FileSystemAuthCacheAdapter(authCachePath);\n }\n return new InMemoryAuthCacheAdapter();\n}\n\nfunction normalizeConfiguredAuthCachePath(path: string | undefined): string | null {\n if (path === undefined) return null;\n const trimmed = path.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction resolveDefaultAuthCachePath(resolveHomeDirectory: () => string): string | null {\n try {\n return join(resolveHomeDirectory(), \".config\", \"capxul\", \"auth-cache.json\");\n } catch {\n return null;\n }\n}\n"],"mappings":";;;;;;;AA0BA,SAAS,eAA4B;CACnC,OAAO;EAAE,SAAS;EAAM,KAAK;CAAK;AACpC;AAEA,MAAM,wBAAwB,MAAM,MAAM,eAAe,OAAO,SAAS,KAAK;AAE9E,IAAa,6BAAb,MAAiE;CAC/D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,MAAc,UAA0C,uBAAuB;EACzF,KAAK,OAAO;EACZ,KAAK,UAAU;EACf,MAAM,OAAO;EAEb,KAAK,aAAa,KAAK,IACrB,cACA,KAAK,KAAK,EAAE,KAAK,OAAO,KAAK,YAAY,QAAQ,OAAO,CAAC,CAC3D;EACA,KAAK,cAAc,YACjB,KAAK,IACH,cACA,OAAO,IAAI,aAAa;GACtB,MAAM,MAAM,OAAO,KAAK,KAAK;GAC7B,OAAO,KAAK,MAAM;IAAE;IAAS,KAAK,IAAI;GAAI,CAAC;EAC7C,CAAC,CACH;EACF,KAAK,eAAe,KAAK,IACvB,gBACA,OAAO,IAAI,aAAa;GACtB,MAAM,MAAM,OAAO,KAAK,KAAK;GAC7B,OAAO,KAAK,MAAM;IAAE,SAAS;IAAM,KAAK,IAAI;GAAI,CAAC;EACnD,CAAC,CACH;EACA,KAAK,SAAS,KAAK,IAAI,UAAU,KAAK,KAAK,EAAE,KAAK,OAAO,KAAK,YAAY,QAAQ,GAAG,CAAC,CAAC;EACvF,KAAK,UAAU,QACb,KAAK,IACH,UACA,OAAO,IAAI,aAAa;GACtB,MAAM,MAAM,OAAO,KAAK,KAAK;GAC7B,OAAO,KAAK,MAAM;IAAE,SAAS,IAAI;IAAS;GAAI,CAAC;EACjD,CAAC,CACH;EACF,KAAK,WAAW,KAAK,IACnB,YACA,OAAO,IAAI,aAAa;GACtB,MAAM,MAAM,OAAO,KAAK,KAAK;GAC7B,OAAO,KAAK,MAAM;IAAE,SAAS,IAAI;IAAS,KAAK;GAAK,CAAC;EACvD,CAAC,CACH;CACF;CAEA,OAA2F;EACzF,MAAM,OAAO;EACb,OAAO,OAAO,IAAI,aAAa;GAC7B,MAAM,KAAK,OAAOA,WAAmB;GAErC,IAAI,EAAC,OADiB,GAAG,OAAO,KAAK,IAAI,IAC5B,OAAO,aAAa;GACjC,MAAM,MAAM,OAAO,GAAG,eAAe,KAAK,MAAM,OAAO;GAEvD,IAAI;GACJ,IAAI;IACF,SAAS,KAAK,MAAM,GAAG;GACzB,QAAQ;IACN,OAAO,aAAa;GACtB;GACA,IAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GACvE,OAAO,aAAa;GAEtB,MAAM,UAAU;GAEhB,OAAO;IACL,SAAS,iBAAiB,QAAQ,OAAO;IACzC,KAAK,eAAe,QAAQ,GAAG;GACjC;EACF,CAAC;CACH;CAEA,MACE,SACqE;EACrE,MAAM,OAAO;EACb,OAAO,OAAO,IAAI,aAAa;GAC7B,MAAM,KAAK,OAAOA,WAAmB;GAErC,MAAM,OAAM,OADQC,KAAa,MAChB,QAAQ,KAAK,IAAI;GAElC,IAAI,EAAC,OADoB,GAAG,OAAO,GAAG,IAEpC,OAAO,GAAG,cAAc,KAAK;IAAE,WAAW;IAAM,MAAM;GAAM,CAAC;GAE/D,OAAO,GAAG,gBAAgB,KAAK,MAAM,KAAK,UAAU,OAAO,GAAG,EAAE,MAAM,IAAM,CAAC;GAC7E,OAAO,GAAG,MAAM,KAAK,MAAM,GAAK;EAClC,CAAC;CACH;CAEA,IACE,WACA,QACkC;EAClC,OAAO,OAAO,KACZ,OAAO,UAAU,UAAU,iBAAiB,WAAW,KAAK,CAAC,GAC7D,OAAO,QAAQ,KAAK,OAAO,CAC7B;CACF;AACF;AAEA,SAAgB,yBAAyB,OAGS;CAChD,OAAO,MAAM,OACX,kBACA,OAAO,WAAW,IAAI,2BAA2B,MAAM,MAAM,MAAM,OAAO,CAAC,EAAE,KAC3E,OAAO,UAAU,UAAU,iBAAiB,cAAc,KAAK,CAAC,CAClE,CACF;AACF;AAEA,SAAS,iBAAiB,WAAmB,OAAgC;CAC3E,OAAO,IAAI,eAAe;EAAE;EAAW;CAAM,CAAC;AAChD;;;;;;;;ACrHA,SAAgB,sBAAsB,OAAmD;CACvF,MAAM,UAAU,oBAAoB,MAAM,UAAU;CACpD,OAAO;EACL,QAAQ;EACR,MAAM,aAAa;GACjB,OAAO,UAAU,QAAQ,OAAO;EAClC;EACA,MAAM,eAAe,MAAyB;GAG5C,OAAO,QAAQ,KAAK,EAAE,KAAK,CAAC;EAC9B;CACF;AACF;;;;;;;;;;;AAYA,SAAgB,2BACd,UAA6C,CAAC,GAC/B;CACf,MAAM,YAAY;CAIlB,IAAI,UAAU,QAAQ,iBAAiB,KAAA,GACrC,OAAO,IAAI,wBAAwB,UAAU,OAAO,YAAY;CAElE,IAAI,UAAU,SAAS,UAAU,SAAS,KAAA,GAAW;EACnD,MAAM,gBACJ,iCAAiC,QAAQ,aAAa,KACtD,4BAA4B,QAAQ,wBAAwB,GAAG,OAAO;EACxE,IAAI,kBAAkB,MAAM,OAAO,IAAI,2BAA2B,aAAa;CACjF;CACA,OAAO,IAAI,yBAAyB;AACtC;AAEA,SAAS,iCAAiC,MAAyC;CACjF,IAAI,SAAS,KAAA,GAAW,OAAO;CAC/B,MAAM,UAAU,KAAK,KAAK;CAC1B,OAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAEA,SAAS,4BAA4B,sBAAmD;CACtF,IAAI;EACF,OAAO,KAAK,qBAAqB,GAAG,WAAW,UAAU,iBAAiB;CAC5E,QAAQ;EACN,OAAO;CACT;AACF"}
@@ -0,0 +1,301 @@
1
+ import { Account, Hex } from "viem";
2
+ import { Context, Effect } from "effect";
3
+
4
+ //#region ../errors/src/errors.d.ts
5
+ declare const CAPXUL_ERROR_CODES: readonly ["NOT_AUTHENTICATED", "EMAIL_DELIVERY_FAILED", "PROFILE_NOT_FOUND", "SMART_ACCOUNT_MISSING", "PLAYER_NOT_FOUND", "ACCOUNT_NOT_FOUND", "PROVIDER_ERROR", "INVALID_INPUT", "ENV_MISSING", "NOT_IMPLEMENTED", "VERIFICATION_REQUIRED", "INSUFFICIENT_BALANCE", "INVALID_RECIPIENT", "ROLE_PERMISSION_DENIED", "TRANSACTION_FAILED", "RATE_LIMITED", "NETWORK_ERROR", "UNKNOWN", "OTP_EXPIRED", "SIGNER_REJECTED", "CANCELLED", "WRONG_STATE", "STALE_EPOCH", "SUPERSEDED", "WORK_DIED", "ACTOR_STOPPED"];
6
+ type CapxulErrorCode = (typeof CAPXUL_ERROR_CODES)[number];
7
+ /**
8
+ * Why an auth/provider call failed — a flat CAUSE enum. The *where* (which
9
+ * OpenFort operation) stays in the separate `operation` detail field; this
10
+ * names the root cause so a single `$exception` can be triaged without
11
+ * parsing the message. Five members, no free strings:
12
+ *
13
+ * - `auth-origin-mismatch`: OTP cookies live on `localhost:PORT` but OpenFort
14
+ * hits the Convex host → no session reaches the provider.
15
+ * - `stale-openfort-cache`: an old `userId` in scoped storage makes the SDK
16
+ * skip re-auth → 401 on `v2/accounts`.
17
+ * - `app-env-allowlist`: the selected app/deployment origin is not allowlisted
18
+ * → 401.
19
+ * - `no-secure-context`: sandboxed/headless browser with no Web Crypto, so
20
+ * `getAddress`/`configure` can never produce an address. Previously vanished
21
+ * into `unknown`; the signer's secure-context probe now names it.
22
+ * - `unknown`: catch-all when no cause could be determined.
23
+ */
24
+ type FailureMode = "auth-origin-mismatch" | "stale-openfort-cache" | "app-env-allowlist" | "no-secure-context" | "unknown";
25
+ /**
26
+ * The one failure representation carried by domain state, actor work, and
27
+ * public error projection. Keeping it beside the canonical error catalog
28
+ * prevents a machine or shell from inventing a second code vocabulary.
29
+ */
30
+ interface Failure {
31
+ readonly code: CapxulErrorCode;
32
+ readonly message: string;
33
+ readonly mode?: FailureMode;
34
+ }
35
+ type CapxulErrorDetails = Record<string, unknown>;
36
+ type CapxulErrorOptions = {
37
+ readonly cause?: unknown;
38
+ readonly details?: CapxulErrorDetails;
39
+ readonly correlationId?: string;
40
+ readonly layer?: string;
41
+ };
42
+ declare class CapxulError extends Error {
43
+ readonly code: CapxulErrorCode;
44
+ readonly details?: CapxulErrorDetails;
45
+ readonly correlationId?: string;
46
+ readonly layer?: string;
47
+ constructor(code: CapxulErrorCode, message: string, options?: CapxulErrorOptions);
48
+ }
49
+ declare function isCapxulError(value: unknown): value is CapxulError;
50
+ //#endregion
51
+ //#region ../types/src/brand.d.ts
52
+ /**
53
+ * Nominal type helper. `Brand<T, B>` is structurally a `T` at runtime but
54
+ * distinct at compile time, preventing accidental swaps between primitives.
55
+ *
56
+ * @internal
57
+ */
58
+ declare const brand: unique symbol;
59
+ type Brand<T, B extends string> = T & {
60
+ readonly [brand]: B;
61
+ };
62
+ //#endregion
63
+ //#region ../types/src/index.d.ts
64
+ type Address = Brand<string, "Address">;
65
+ type Email = Brand<string, "Email">;
66
+ type Profile$1 = {
67
+ readonly authUserId: AuthUserId;
68
+ readonly email: Email;
69
+ readonly displayName: string | null;
70
+ readonly country: CountryCode | null;
71
+ readonly onboarded: boolean;
72
+ readonly withdrawalAddress: Address | null;
73
+ readonly username: string | null;
74
+ readonly imageUrl: string | null;
75
+ readonly kycTier: KycTier;
76
+ readonly createdAt: EpochMs;
77
+ readonly updatedAt: EpochMs;
78
+ };
79
+ type SmartAccount$1 = {
80
+ readonly authUserId: AuthUserId;
81
+ readonly signerAddress: Address | null;
82
+ readonly smartAccountAddress: Address;
83
+ readonly chainId: ChainId;
84
+ readonly deployedAt: EpochMs | null;
85
+ readonly claimedAt: EpochMs | null;
86
+ readonly createdAt: EpochMs;
87
+ };
88
+ type Money = {
89
+ readonly currency: CurrencyCode;
90
+ readonly value: string;
91
+ readonly decimals: number;
92
+ };
93
+ type Account$1 = {
94
+ readonly id: AccountId;
95
+ readonly balance: Money;
96
+ readonly available: Money;
97
+ };
98
+ /** Named bucket partitioning a logical Account (canon §9). */
99
+ type SubAccount = {
100
+ readonly id: SubAccountId;
101
+ readonly accountId: AccountId;
102
+ readonly name: string;
103
+ readonly balance: Money;
104
+ readonly createdAt: EpochMs;
105
+ };
106
+ type AuthUserId = Brand<string, "AuthUserId">;
107
+ type AnonymousDistinctId = Brand<string, "AnonymousDistinctId">;
108
+ type AccountId = Brand<string, "AccountId">;
109
+ type SubAccountId = Brand<string, "SubAccountId">;
110
+ type OrgId = Brand<string, "OrgId">;
111
+ type AppId = Brand<string, "AppId">;
112
+ type AllowedOrigin = Brand<string, "AllowedOrigin">;
113
+ type PublishableKey = Brand<string, "PublishableKey">;
114
+ type DurationMs = Brand<number, "DurationMs">;
115
+ type TxHash = Brand<string, "TxHash">;
116
+ type DocumentHash = Brand<string, "DocumentHash">;
117
+ type EpochMs = Brand<number, "EpochMs">;
118
+ type EpochSeconds = Brand<number, "EpochSeconds">;
119
+ type ChainId = Brand<number, "ChainId">;
120
+ type CountryCode = Brand<string, "CountryCode">;
121
+ type CurrencyCode = Brand<SupportedCurrencyCode, "CurrencyCode">;
122
+ type KycTier = Brand<0 | 1 | 2 | 3, "KycTier">;
123
+ type BlockNumber = Brand<number, "BlockNumber">;
124
+ type RunId = Brand<string, "RunId">;
125
+ type RoleKey = Brand<string, "RoleKey">;
126
+ type SessionToken = Brand<string, "SessionToken">;
127
+ type JwtToken = Brand<string, "JwtToken">;
128
+ type AuthSession = {
129
+ readonly authUserId: AuthUserId;
130
+ readonly email: Email;
131
+ readonly token: SessionToken;
132
+ readonly expiresAt: EpochMs;
133
+ };
134
+ declare const SUPPORTED_CURRENCIES: readonly [{
135
+ readonly code: "USD";
136
+ readonly symbol: "$";
137
+ readonly name: "US Dollar";
138
+ }, {
139
+ readonly code: "NGN";
140
+ readonly symbol: "NGN";
141
+ readonly name: "Nigerian Naira";
142
+ }, {
143
+ readonly code: "GHS";
144
+ readonly symbol: "GHS";
145
+ readonly name: "Ghanaian Cedi";
146
+ }, {
147
+ readonly code: "KES";
148
+ readonly symbol: "KSh";
149
+ readonly name: "Kenyan Shilling";
150
+ }, {
151
+ readonly code: "UGX";
152
+ readonly symbol: "USh";
153
+ readonly name: "Ugandan Shilling";
154
+ }];
155
+ type SupportedCurrencyCode = (typeof SUPPORTED_CURRENCIES)[number]["code"];
156
+ declare function toAddress(raw: unknown): Address;
157
+ declare function toCountryCode(raw: unknown): CountryCode;
158
+ //#endregion
159
+ //#region src/ports/auth-cache.d.ts
160
+ /**
161
+ * AuthCachePort (TA4) — replaces `SessionStoragePort` in the rebuild slice's
162
+ * consumer-facing wiring. Stores the user-snapshot Session AND the cached
163
+ * Convex JWT (W7 bridge endpoint). The two slots are independent so a session
164
+ * refresh doesn't invalidate the JWT and vice versa.
165
+ *
166
+ * Three adapters (TA7):
167
+ * - `BrowserAuthCacheAdapter` — backed by `localStorage`
168
+ * - `FileSystemAuthCacheAdapter` — mode-0600 JSON file in `~/.config/capxul/`
169
+ * - `InMemoryAuthCacheAdapter` — for tests
170
+ *
171
+ * `SessionStoragePort` was retired by the Stage 4 rebuild; session and JWT
172
+ * persistence now share this cache boundary.
173
+ */
174
+ interface AuthCachePort {
175
+ readonly getSession: Effect.Effect<AuthSession | null, AuthCacheError>;
176
+ readonly setSession: (session: AuthSession) => Effect.Effect<void, AuthCacheError>;
177
+ readonly clearSession: Effect.Effect<void, AuthCacheError>;
178
+ /**
179
+ * JWT cache for the `/api/auth/convex/token` bridge endpoint (W7).
180
+ * Stored separately from the session so a session refresh doesn't
181
+ * invalidate cached JWT.
182
+ */
183
+ readonly getJwt: Effect.Effect<CachedJwt | null, AuthCacheError>;
184
+ readonly setJwt: (jwt: CachedJwt) => Effect.Effect<void, AuthCacheError>;
185
+ readonly clearJwt: Effect.Effect<void, AuthCacheError>;
186
+ }
187
+ /**
188
+ * Cached Convex JWT shape (TA4). `expEpochSeconds` is decoded from the JWT's
189
+ * `exp` claim at fetch time so the `tokenProvider` cache eviction logic can
190
+ * proactively refresh at `exp - 30s` per TA3.
191
+ */
192
+ interface CachedJwt {
193
+ readonly token: JwtToken;
194
+ readonly expEpochSeconds: EpochSeconds;
195
+ }
196
+ declare const AuthCacheError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => import("effect/Cause").YieldableError & {
197
+ readonly _tag: "AuthCacheError";
198
+ } & Readonly<A>;
199
+ declare class AuthCacheError extends AuthCacheError_base<{
200
+ readonly operation: string;
201
+ readonly cause: unknown;
202
+ }> {}
203
+ declare const AuthCachePortTag_base: Context.ServiceClass<AuthCachePortTag, "@capxul/sdk/ports/AuthCachePort", AuthCachePort>;
204
+ declare class AuthCachePortTag extends AuthCachePortTag_base {}
205
+ //#endregion
206
+ //#region src/surface/types.d.ts
207
+ type Session = AuthSession;
208
+ type Profile = Profile$1;
209
+ type SmartAccount = SmartAccount$1;
210
+ /**
211
+ * Result-shape returned by every method on `CapxulClient`. Mirrors the
212
+ * existing per-port `Result` aliases; centralized here so consumers have
213
+ * a single import for the consumer-facing surface.
214
+ */
215
+ type CapxulResult<T> = {
216
+ readonly ok: true;
217
+ readonly value: T;
218
+ } | {
219
+ readonly ok: false;
220
+ readonly error: CapxulError;
221
+ };
222
+ //#endregion
223
+ //#region src/surface/account-providers.d.ts
224
+ type AccountProviderSource = "local-private-key" | "openfort-embedded" | "injected-eip1193";
225
+ type AccountRequirement = "none" | "counterfactual" | "deployed";
226
+ interface AccountProvider {
227
+ readonly source: AccountProviderSource;
228
+ /**
229
+ * Resolve the signer's EVM address.
230
+ *
231
+ * @determinism MUST return the same `Address` across calls for the
232
+ * lifetime of a single provider instance — the SDK-level deploy mutex
233
+ * keys on `(authUserId, safeAddress)` where `safeAddress` is computed
234
+ * from `getAddress()`'s result before the port's `prepare()` round-trip.
235
+ * If two successive calls returned different addresses, concurrent
236
+ * `deploySafe` invocations would compute different mutex keys and
237
+ * bypass dedup, defeating the mutex.
238
+ *
239
+ * The two sanctioned providers both satisfy this invariant:
240
+ * - `localPrivateKeyAccountProvider` — derives once from the key
241
+ * - `eip1193AccountProvider` — reads `eth_accounts` (idempotent once
242
+ * the wallet is connected; consumer is responsible for connection)
243
+ *
244
+ * The Openfort embedded path no longer needs a provider: the
245
+ * `openfortEmbeddedSigner` `CapxulSigner` caches its own address and the
246
+ * deploy is backend-orchestrated (backend-orchestrated-deploy.md).
247
+ *
248
+ * Custom providers MUST honor this contract.
249
+ */
250
+ getAddress(): Promise<CapxulResult<Address>>;
251
+ getDeployAccount(): Promise<CapxulResult<Account>>;
252
+ }
253
+ interface Eip1193Provider {
254
+ request(args: {
255
+ readonly method: string;
256
+ readonly params?: readonly unknown[];
257
+ }): Promise<unknown>;
258
+ }
259
+ declare function localPrivateKeyAccountProvider(input: {
260
+ readonly privateKey: Hex;
261
+ }): AccountProvider;
262
+ declare function eip1193AccountProvider(input: {
263
+ readonly provider: Eip1193Provider;
264
+ }): AccountProvider;
265
+ //#endregion
266
+ //#region src/signer.d.ts
267
+ interface CapxulDigestSigner {
268
+ /**
269
+ * Sign the EIP-712 `SafeOp` digest the backend returns for the prepared
270
+ * deployment UserOperation. Returns the raw 65-byte ECDSA signature; the
271
+ * backend packs `validAfter|validUntil|signature`.
272
+ */
273
+ signUserOpHash(hash: Hex): Promise<Hex>;
274
+ }
275
+ interface CapxulSigner extends CapxulDigestSigner {
276
+ /**
277
+ * Signer kind — surfaced on the `accountProviderReady` status so the
278
+ * readiness ladder reports which signer the consumer wired.
279
+ */
280
+ readonly source: AccountProviderSource;
281
+ /** Owner EOA address — the Safe's single owner. */
282
+ getAddress(): Promise<Address>;
283
+ }
284
+ /** Minimal EIP-1193 surface an injected browser wallet exposes. */
285
+ interface Eip1193RequestProvider {
286
+ request(args: {
287
+ readonly method: string;
288
+ readonly params?: readonly unknown[];
289
+ }): Promise<unknown>;
290
+ }
291
+ /**
292
+ * Browser `CapxulSigner` backed by an injected EIP-1193 wallet (MetaMask, etc.).
293
+ * Signs the SafeOp digest via `eth_sign`, then verifies the returned signature
294
+ * recovers the selected account against that raw digest. Wallets that prefix
295
+ * `eth_sign` payloads are rejected before the backend submits an invalid SafeOp.
296
+ * The node key signer lives in `@capxul/sdk/node` (`localPrivateKeySigner`).
297
+ */
298
+ declare function injectedWalletSigner(provider: Eip1193RequestProvider): CapxulSigner;
299
+ //#endregion
300
+ export { isCapxulError as $, CurrencyCode as A, RunId as B, AnonymousDistinctId as C, BlockNumber as D, AuthUserId as E, Money as F, TxHash as G, SmartAccount$1 as H, OrgId as I, CapxulError as J, toAddress as K, Profile$1 as L, DurationMs as M, Email as N, ChainId as O, EpochMs as P, FailureMode as Q, PublishableKey as R, AllowedOrigin as S, AuthSession as T, SubAccount as U, SessionToken as V, SubAccountId as W, CapxulErrorDetails as X, CapxulErrorCode as Y, Failure as Z, AuthCachePortTag as _, AccountProvider as a, AccountId as b, Eip1193Provider as c, CapxulResult as d, Profile as f, AuthCachePort as g, AuthCacheError as h, injectedWalletSigner as i, DocumentHash as j, CountryCode as k, eip1193AccountProvider as l, SmartAccount as m, CapxulSigner as n, AccountProviderSource as o, Session as p, toCountryCode as q, Eip1193RequestProvider as r, AccountRequirement as s, CapxulDigestSigner as t, localPrivateKeyAccountProvider as u, CachedJwt as v, AppId as w, Address as x, Account$1 as y, RoleKey as z };
301
+ //# sourceMappingURL=signer-CJT0pPiO.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer-CJT0pPiO.d.mts","names":[],"sources":["../../errors/src/errors.ts","../../types/src/brand.ts","../../types/src/index.ts","../src/ports/auth-cache.ts","../src/surface/types.ts","../src/surface/account-providers.ts","../src/signer.ts"],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { an as TelemetryEvent, gn as IdentityTransition, on as TelemetryGroupInput, sn as TelemetryIdentifyInput, t as CapxulClient } from "../create-capxul-client-C7H5b68l.mjs";
2
+ import { Effect, Layer } from "effect";
3
+
4
+ //#region src/testing/telemetry/RecordingTelemetryAdapter.d.ts
5
+ type RecordingTelemetryOperation = {
6
+ readonly type: "emit";
7
+ readonly event: TelemetryEvent;
8
+ } | {
9
+ readonly type: "identify";
10
+ readonly input: TelemetryIdentifyInput;
11
+ } | {
12
+ readonly type: "group";
13
+ readonly input: TelemetryGroupInput;
14
+ } | {
15
+ readonly type: "reset";
16
+ };
17
+ //#endregion
18
+ //#region src/testing/index.d.ts
19
+ interface CreateCapxulTestClientOptions {
20
+ readonly requirement?: "none" | "counterfactual" | "deployed";
21
+ }
22
+ interface SeedTestIdentityInput {
23
+ readonly authUserId: string;
24
+ readonly email: string;
25
+ readonly displayName?: string;
26
+ readonly country?: string;
27
+ }
28
+ interface CapxulTestClient {
29
+ readonly client: CapxulClient;
30
+ readonly clock: CapxulTestClock;
31
+ readonly observation: CapxulTestObservation;
32
+ readonly transitions: readonly IdentityTransition[];
33
+ readonly observations: readonly RecordingTelemetryOperation[];
34
+ readonly peekOtp: (email: string) => string | undefined;
35
+ readonly seedIdentity: (input: SeedTestIdentityInput) => Promise<void>;
36
+ readonly close: () => Promise<void>;
37
+ }
38
+ interface CapxulTestClock {
39
+ readonly advance: (ms: number) => Promise<void>;
40
+ }
41
+ interface CapxulTestObservation {
42
+ readonly emit: (event: TelemetryEvent) => Promise<void>;
43
+ readonly identify: (input: TelemetryIdentifyInput) => Promise<void>;
44
+ readonly group: (input: TelemetryGroupInput) => Promise<void>;
45
+ readonly reset: () => Promise<void>;
46
+ }
47
+ /**
48
+ * Assemble the real public client over deterministic in-memory ports.
49
+ * Unconfigured backend calls fail locally; no adapter owns a network exit.
50
+ */
51
+ declare function createCapxulTestClient(options?: CreateCapxulTestClientOptions): CapxulTestClient;
52
+ //#endregion
53
+ export { CapxulTestClient, CapxulTestClock, CapxulTestObservation, CreateCapxulTestClientOptions, SeedTestIdentityInput, createCapxulTestClient };
54
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/testing/telemetry/RecordingTelemetryAdapter.ts","../../src/testing/index.ts"],"mappings":";;;;KAYY,2BAAA;EAAA,SACG,IAAA;EAAA,SAAuB,KAAA,EAAO,cAAA;AAAA;EAAA,SAC9B,IAAA;EAAA,SAA2B,KAAA,EAAO,sBAAA;AAAA;EAAA,SAClC,IAAA;EAAA,SAAwB,KAAA,EAAO,mBAAA;AAAA;EAAA,SAC/B,IAAA;AAAA;;;UCoCE,6BAAA;EAAA,SACN,WAAW;AAAA;AAAA,UAGL,qBAAA;EAAA,SACN,UAAA;EAAA,SACA,KAAA;EAAA,SACA,WAAA;EAAA,SACA,OAAA;AAAA;AAAA,UAGM,gBAAA;EAAA,SACN,MAAA,EAAQ,YAAA;EAAA,SACR,KAAA,EAAO,eAAA;EAAA,SACP,WAAA,EAAa,qBAAA;EAAA,SACb,WAAA,WAAsB,kBAAA;EAAA,SACtB,YAAA,WAAuB,2BAAA;EAAA,SACvB,OAAA,GAAU,KAAA;EAAA,SACV,YAAA,GAAe,KAAA,EAAO,qBAAA,KAA0B,OAAA;EAAA,SAChD,KAAA,QAAa,OAAA;AAAA;AAAA,UAGP,eAAA;EAAA,SACN,OAAA,GAAU,EAAA,aAAe,OAAO;AAAA;AAAA,UAG1B,qBAAA;EAAA,SACN,IAAA,GAAO,KAAA,EAAO,cAAA,KAAmB,OAAA;EAAA,SACjC,QAAA,GAAW,KAAA,EAAO,sBAAA,KAA2B,OAAA;EAAA,SAC7C,KAAA,GAAQ,KAAA,EAAO,mBAAA,KAAwB,OAAA;EAAA,SACvC,KAAA,QAAa,OAAA;AAAA;AA1BxB;;;;AAAA,iBAiCgB,sBAAA,CACd,OAAA,GAAS,6BAAA,GACR,gBAAgB"}