@ab-org/sdk-core 0.1.1 → 0.1.2-beta.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.
@@ -0,0 +1,363 @@
1
+ import { CubeSignerAuth, createCubistEvmWalletProvider } from './chunk-5HURLKIK.js';
2
+
3
+ // src/core/chains.ts
4
+ var chainDescriptors = {
5
+ AB_CORE: {
6
+ chain: "AB_CORE",
7
+ namespace: "ab-core",
8
+ reference: "ab:core",
9
+ label: "AB Core",
10
+ rpcFamily: "custom",
11
+ supportsSmartSessions: true,
12
+ supportsAccountAbstraction: true
13
+ },
14
+ ETH: {
15
+ chain: "ETH",
16
+ namespace: "evm",
17
+ reference: "eip155:1",
18
+ label: "Ethereum",
19
+ rpcFamily: "evm",
20
+ evmChainId: 1,
21
+ supportsSmartSessions: true,
22
+ supportsAccountAbstraction: true
23
+ },
24
+ BSC: {
25
+ chain: "BSC",
26
+ namespace: "evm",
27
+ reference: "eip155:56",
28
+ label: "BNB Smart Chain",
29
+ rpcFamily: "evm",
30
+ evmChainId: 56,
31
+ supportsSmartSessions: true,
32
+ supportsAccountAbstraction: false
33
+ },
34
+ ETH_TENDERLY: {
35
+ chain: "ETH_TENDERLY",
36
+ namespace: "evm",
37
+ reference: "eip155:3030",
38
+ label: "Ethereum Tenderly",
39
+ rpcFamily: "evm",
40
+ evmChainId: 3030,
41
+ supportsSmartSessions: true,
42
+ supportsAccountAbstraction: true
43
+ },
44
+ BSC_TENDERLY: {
45
+ chain: "BSC_TENDERLY",
46
+ namespace: "evm",
47
+ reference: "eip155:3131",
48
+ label: "BNB Smart Chain Tenderly",
49
+ rpcFamily: "evm",
50
+ evmChainId: 3131,
51
+ supportsSmartSessions: true,
52
+ supportsAccountAbstraction: false
53
+ },
54
+ SOL: {
55
+ chain: "SOL",
56
+ namespace: "solana",
57
+ reference: "solana:mainnet-beta",
58
+ label: "Solana",
59
+ rpcFamily: "solana",
60
+ supportsSmartSessions: true,
61
+ supportsAccountAbstraction: false
62
+ }
63
+ };
64
+ var getChainDescriptor = (chain) => chainDescriptors[chain];
65
+ var getAllChainDescriptors = () => Object.values(chainDescriptors);
66
+ var normalizeEvmChainId = (value) => {
67
+ if (typeof value === "number") return value;
68
+ if (typeof value === "bigint") return Number(value);
69
+ return Number(BigInt(value));
70
+ };
71
+ var getSupportedChainFromEvmChainId = (value) => {
72
+ const chainId = normalizeEvmChainId(value);
73
+ const descriptor = getAllChainDescriptors().find(
74
+ (item) => item.namespace === "evm" && item.evmChainId === chainId
75
+ );
76
+ if (!descriptor) {
77
+ throw new Error(`Unsupported EVM chainId: ${chainId}`);
78
+ }
79
+ return descriptor.chain;
80
+ };
81
+ var createChainContext = (walletChain, settlementChain = walletChain) => ({
82
+ walletChain,
83
+ walletChainDescriptor: getChainDescriptor(walletChain),
84
+ settlementChain,
85
+ settlementChainDescriptor: getChainDescriptor(settlementChain)
86
+ });
87
+
88
+ // src/core/capabilities.ts
89
+ var SessionCapabilityError = class extends Error {
90
+ constructor(message) {
91
+ super(message);
92
+ this.name = "SessionCapabilityError";
93
+ }
94
+ };
95
+ var toBigIntAmount = (value) => {
96
+ if (typeof value === "bigint") return value;
97
+ if (typeof value === "number") return BigInt(value);
98
+ return BigInt(value);
99
+ };
100
+ var createSessionCapabilityPolicy = (input = {}) => ({
101
+ id: input.id ?? `cap:${Date.now()}`,
102
+ appId: input.appId,
103
+ origin: input.origin,
104
+ expiresAt: input.expiresAt,
105
+ methods: input.methods,
106
+ chains: input.chains,
107
+ tokens: input.tokens,
108
+ maxAmount: input.maxAmount,
109
+ revocable: input.revocable ?? true,
110
+ metadata: input.metadata
111
+ });
112
+ var isSessionExpired = (session, now = Date.now()) => Boolean(session?.expiresAt && session.expiresAt <= now);
113
+ var isCapabilityPolicyExpired = (policy, now = Date.now()) => Boolean(policy?.expiresAt && policy.expiresAt <= now);
114
+ var sessionSupportsCapability = (session, capability) => {
115
+ const capabilities = session?.capabilities;
116
+ if (!capabilities || capabilities.length === 0) return true;
117
+ return capabilities.includes(capability);
118
+ };
119
+ var describeSessionCapabilityPolicy = (policy) => {
120
+ if (!policy) return [];
121
+ const lines = [];
122
+ if (policy.origin) lines.push(`Origin: ${policy.origin}`);
123
+ if (policy.appId) lines.push(`App: ${policy.appId}`);
124
+ if (policy.methods?.length) lines.push(`Methods: ${policy.methods.join(", ")}`);
125
+ if (policy.chains?.length) lines.push(`Chains: ${policy.chains.join(", ")}`);
126
+ if (policy.tokens?.length) lines.push(`Tokens: ${policy.tokens.join(", ")}`);
127
+ if (policy.maxAmount) lines.push(`Max amount: ${policy.maxAmount}`);
128
+ if (policy.expiresAt) lines.push(`Expires at: ${new Date(policy.expiresAt).toISOString()}`);
129
+ return lines;
130
+ };
131
+ var assertSessionCapability = (session, check) => {
132
+ const now = check.now ?? Date.now();
133
+ if (isSessionExpired(session, now)) {
134
+ throw new SessionCapabilityError("Wallet session has expired");
135
+ }
136
+ const policy = session.capabilityPolicy;
137
+ if (isCapabilityPolicyExpired(policy, now)) {
138
+ throw new SessionCapabilityError("Capability session has expired");
139
+ }
140
+ if (!sessionSupportsCapability(session, check.capability)) {
141
+ throw new SessionCapabilityError(
142
+ `Wallet session does not support capability "${check.capability}"`
143
+ );
144
+ }
145
+ if (!policy) return;
146
+ if (policy.appId && check.appId && policy.appId !== check.appId) {
147
+ throw new SessionCapabilityError("Capability session is scoped to a different app");
148
+ }
149
+ if (policy.origin && check.origin && policy.origin !== check.origin) {
150
+ throw new SessionCapabilityError("Capability session is scoped to a different origin");
151
+ }
152
+ if (policy.methods?.length && !policy.methods.includes(check.capability)) {
153
+ throw new SessionCapabilityError(
154
+ `Capability "${check.capability}" is not allowed for this session`
155
+ );
156
+ }
157
+ if (check.chain && policy.chains?.length && !policy.chains.includes(check.chain)) {
158
+ throw new SessionCapabilityError(`Chain "${check.chain}" is not allowed for this session`);
159
+ }
160
+ if (check.token && policy.tokens?.length && !policy.tokens.includes(check.token)) {
161
+ throw new SessionCapabilityError(`Token "${check.token}" is not allowed for this session`);
162
+ }
163
+ if (policy.maxAmount && check.amount !== void 0) {
164
+ if (toBigIntAmount(check.amount) > toBigIntAmount(policy.maxAmount)) {
165
+ throw new SessionCapabilityError("Requested amount exceeds the capability session limit");
166
+ }
167
+ }
168
+ };
169
+
170
+ // src/providers/base.ts
171
+ var AbstractProvider = class {
172
+ constructor() {
173
+ this.currentSession = null;
174
+ }
175
+ async disconnect() {
176
+ this.clearSession();
177
+ }
178
+ setSession(session) {
179
+ this.currentSession = session;
180
+ return session;
181
+ }
182
+ clearSession() {
183
+ this.currentSession = null;
184
+ }
185
+ get session() {
186
+ return this.currentSession;
187
+ }
188
+ requireSession(message = `${this.title} session missing`) {
189
+ if (!this.currentSession) {
190
+ throw new Error(message);
191
+ }
192
+ return this.currentSession;
193
+ }
194
+ getProvider() {
195
+ return this.currentSession?.provider ?? null;
196
+ }
197
+ async reconnect(_persistedSession) {
198
+ return null;
199
+ }
200
+ };
201
+
202
+ // src/providers/social/baseSocialProvider.ts
203
+ var AbstractSocialProvider = class extends AbstractProvider {
204
+ constructor() {
205
+ super(...arguments);
206
+ this.category = "social";
207
+ }
208
+ async connect(args) {
209
+ await this.signIn(args?.options, args?.payload);
210
+ return this.requireSession();
211
+ }
212
+ };
213
+
214
+ // src/providers/social/cubistProvider.ts
215
+ var defaultAdapter = {
216
+ async resolve(session) {
217
+ const keys = await session.client.sessionKeys();
218
+ const evmKey = keys.find((k) => k.cached.key_type === "SecpEthAddr");
219
+ if (!evmKey) throw new Error("No EVM key found in CubeSigner session");
220
+ const address = evmKey.materialId;
221
+ const chain = "ETH";
222
+ const provider = createCubistEvmWalletProvider({
223
+ session,
224
+ address,
225
+ chain
226
+ });
227
+ return {
228
+ address,
229
+ chain,
230
+ provider,
231
+ chainContext: createChainContext(chain)
232
+ };
233
+ }
234
+ };
235
+ var cubistCapabilities = [
236
+ "eth_accounts",
237
+ "eth_requestAccounts",
238
+ "eth_chainId",
239
+ "eth_signTransaction",
240
+ "personal_sign",
241
+ "eth_signTypedData_v4",
242
+ "wallet_disconnect",
243
+ "wallet_rehydrate"
244
+ ];
245
+ var CubistSocialProvider = class extends AbstractSocialProvider {
246
+ constructor(config, adapter = defaultAdapter) {
247
+ super();
248
+ this.id = "cubist";
249
+ this.title = "Cubist Social Wallet";
250
+ this.lastCubeSignerSession = null;
251
+ /** Stash the login method so `connect()` can auto-retry. */
252
+ this.lastLogin = null;
253
+ this.auth = new CubeSignerAuth(config);
254
+ this.adapter = adapter;
255
+ }
256
+ async createWalletSession(method) {
257
+ const session = method.type === "google" ? await this.auth.loginWithGoogle(method.idToken) : await this.auth.loginWithTwitter(method.params);
258
+ this.lastCubeSignerSession = session;
259
+ const walletSession = await this.adapter.resolve(session);
260
+ const capabilityPolicy = this.auth.defaultSessionPolicy ? createSessionCapabilityPolicy(this.auth.defaultSessionPolicy) : void 0;
261
+ return {
262
+ ...walletSession,
263
+ walletType: "social",
264
+ authSource: method.type,
265
+ sessionId: `${method.type}:${walletSession.address.toLowerCase()}`,
266
+ expiresAt: capabilityPolicy?.expiresAt,
267
+ capabilities: cubistCapabilities,
268
+ sessionData: session.sessionData,
269
+ chainContext: walletSession.chainContext ?? createChainContext(walletSession.chain),
270
+ capabilityPolicy
271
+ };
272
+ }
273
+ async authenticate(method) {
274
+ const walletSession = await this.createWalletSession(method);
275
+ this.lastLogin = method;
276
+ this.setSession(walletSession);
277
+ }
278
+ getResolvedLoginMethod(payload) {
279
+ const method = payload ?? this.lastLogin;
280
+ if (!method) {
281
+ throw new Error(
282
+ "CubistSocialProvider.signIn requires a login method. Use signInWith(method) first."
283
+ );
284
+ }
285
+ return method;
286
+ }
287
+ /**
288
+ * Preferred explicit sign-in entrypoint.
289
+ */
290
+ async signInWith(method, _options) {
291
+ await this.authenticate(method);
292
+ }
293
+ /**
294
+ * Backward-compatible abstract implementation.
295
+ *
296
+ * - If `payload` is provided, it is treated as the login method.
297
+ * - Otherwise reuses the previously cached login method if available.
298
+ */
299
+ async signIn(_options, payload) {
300
+ await this.authenticate(this.getResolvedLoginMethod(payload));
301
+ }
302
+ /**
303
+ * Explicit connect flow that both authenticates and returns the wallet session.
304
+ */
305
+ async connectWith(method, options) {
306
+ return this.connect({ options, payload: method });
307
+ }
308
+ async connect(args) {
309
+ if (args?.payload !== void 0 || args?.options !== void 0) {
310
+ await this.signIn(args.options, args.payload);
311
+ return this.requireSession("Cubist session missing after sign-in");
312
+ }
313
+ if (this.session) {
314
+ return this.session;
315
+ }
316
+ if (!this.lastLogin) {
317
+ throw new Error("Cubist session missing \u2014 call signInWith(method) first");
318
+ }
319
+ await this.signIn();
320
+ return this.requireSession("Cubist session missing after sign-in");
321
+ }
322
+ async reconnect(persistedSession) {
323
+ if (!persistedSession.sessionData) return null;
324
+ try {
325
+ const csSession = await this.auth.restoreSession(
326
+ persistedSession.sessionData
327
+ );
328
+ this.lastCubeSignerSession = csSession;
329
+ const walletSession = await this.adapter.resolve(csSession);
330
+ return this.setSession({
331
+ ...walletSession,
332
+ walletType: persistedSession.walletType ?? "social",
333
+ authSource: persistedSession.authSource,
334
+ sessionId: persistedSession.sessionId,
335
+ expiresAt: persistedSession.expiresAt,
336
+ capabilities: cubistCapabilities,
337
+ sessionData: csSession.sessionData,
338
+ chainContext: walletSession.chainContext ?? createChainContext(walletSession.chain),
339
+ capabilityPolicy: persistedSession.capabilityPolicy
340
+ });
341
+ } catch {
342
+ return null;
343
+ }
344
+ }
345
+ async signOut() {
346
+ await this.auth.signOut();
347
+ this.clearSession();
348
+ this.lastLogin = null;
349
+ this.lastCubeSignerSession = null;
350
+ }
351
+ async disconnect() {
352
+ await this.signOut();
353
+ }
354
+ /** Direct access to the underlying CubeSignerAuth for advanced use-cases. */
355
+ get cubeSignerAuth() {
356
+ return this.auth;
357
+ }
358
+ get cubeSignerSession() {
359
+ return this.lastCubeSignerSession ?? this.auth.currentSession;
360
+ }
361
+ };
362
+
363
+ export { AbstractProvider, AbstractSocialProvider, CubistSocialProvider, SessionCapabilityError, assertSessionCapability, createChainContext, createSessionCapabilityPolicy, describeSessionCapabilityPolicy, getAllChainDescriptors, getChainDescriptor, getSupportedChainFromEvmChainId, isCapabilityPolicyExpired, isSessionExpired, sessionSupportsCapability };