@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.
- package/README.md +121 -6
- package/dist/{InMemoryAuthCacheAdapter-v5W-XB5M.mjs → InMemoryAuthCacheAdapter-Dr1sEd9y.mjs} +36 -16
- package/dist/InMemoryAuthCacheAdapter-Dr1sEd9y.mjs.map +1 -0
- package/dist/create-capxul-client-C7H5b68l.d.mts +2764 -0
- package/dist/create-capxul-client-C7H5b68l.d.mts.map +1 -0
- package/dist/create-capxul-client-DiqVIxsV.mjs +6980 -0
- package/dist/create-capxul-client-DiqVIxsV.mjs.map +1 -0
- package/dist/index.d.mts +119 -2020
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2464 -6308
- package/dist/index.mjs.map +1 -1
- package/dist/node/index.d.mts +3 -6
- package/dist/node/index.d.mts.map +1 -1
- package/dist/node/index.mjs +27 -27
- package/dist/node/index.mjs.map +1 -1
- package/dist/signer-CJT0pPiO.d.mts +301 -0
- package/dist/signer-CJT0pPiO.d.mts.map +1 -0
- package/dist/testing/index.d.mts +54 -0
- package/dist/testing/index.d.mts.map +1 -0
- package/dist/testing/index.mjs +1068 -0
- package/dist/testing/index.mjs.map +1 -0
- package/package.json +17 -18
- package/dist/InMemoryAuthCacheAdapter-v5W-XB5M.mjs.map +0 -1
- package/dist/index-CTXgQ_xR.d.mts +0 -158
- package/dist/index-CTXgQ_xR.d.mts.map +0 -1
- package/dist/ports/safe-deployment.d.mts +0 -2
- package/dist/ports/safe-deployment.mjs +0 -38
- package/dist/ports/safe-deployment.mjs.map +0 -1
- package/dist/safe-deployment-D3k9yndM.d.mts +0 -136
- package/dist/safe-deployment-D3k9yndM.d.mts.map +0 -1
- package/dist/signer-DqDtJU1l.d.mts +0 -145
- package/dist/signer-DqDtJU1l.d.mts.map +0 -1
package/dist/node/index.d.mts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import {
|
|
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 =
|
|
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":"
|
|
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"}
|
package/dist/node/index.mjs
CHANGED
|
@@ -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-
|
|
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
|
|
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(
|
|
32
|
-
const cur = yield*
|
|
33
|
-
yield*
|
|
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(
|
|
39
|
-
const cur = yield*
|
|
40
|
-
yield*
|
|
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(
|
|
47
|
-
const cur = yield*
|
|
48
|
-
yield*
|
|
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(
|
|
54
|
-
const cur = yield*
|
|
55
|
-
yield*
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
const
|
|
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(
|
|
89
|
-
yield* fs.chmod(
|
|
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) {
|
package/dist/node/index.mjs.map
CHANGED
|
@@ -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":"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"}
|
|
@@ -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"}
|