@bounded-sh/core 0.0.1
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 +78 -0
- package/dist/client/config.d.ts +105 -0
- package/dist/client/field-values.d.ts +24 -0
- package/dist/client/functions.d.ts +34 -0
- package/dist/client/live-effects.d.ts +120 -0
- package/dist/client/live.d.ts +61 -0
- package/dist/client/operations.d.ts +264 -0
- package/dist/client/realtime-store.d.ts +89 -0
- package/dist/client/subscription-v2.d.ts +92 -0
- package/dist/client/subscription.d.ts +64 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +7807 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +7726 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types.d.ts +157 -0
- package/dist/utils/api.d.ts +11 -0
- package/dist/utils/auth-api.d.ts +10 -0
- package/dist/utils/core-platform.d.ts +16 -0
- package/dist/utils/rn-session-manager.d.ts +84 -0
- package/dist/utils/server-session-manager.d.ts +35 -0
- package/dist/utils/session-manager.d.ts +31 -0
- package/dist/utils/sol/poof4b5pk1L9tmThvBmaABjcyjfhFGbMbQP5BXk2QZpDevnet-program.d.ts +2027 -0
- package/dist/utils/sol/poof4b5pk1L9tmThvBmaABjcyjfhFGbMbQP5BXk2QZpMainnet-program.d.ts +2027 -0
- package/dist/utils/sol/sol-utils.d.ts +40 -0
- package/dist/utils/sol/taro6CvKqwrYrDc16ufYgzQ2NZcyyVKStffbtudrhRuDevnet-program.d.ts +1161 -0
- package/dist/utils/utils.d.ts +41 -0
- package/dist/utils/web-session-manager.d.ts +20 -0
- package/package.json +68 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { PublicKey, TransactionInstruction, Transaction, VersionedTransaction } from "@solana/web3.js";
|
|
2
|
+
import { SetOptions } from "./client/operations";
|
|
3
|
+
export interface AuthProvider {
|
|
4
|
+
login(): Promise<User | null>;
|
|
5
|
+
runTransaction(evmTransactionData?: EVMTransaction, solTransactionData?: SolTransaction, options?: SetOptions): Promise<TransactionResult>;
|
|
6
|
+
signMessage(message: string): Promise<string>;
|
|
7
|
+
signMessageMock?(message: string): Promise<string>;
|
|
8
|
+
signTransaction(transaction: Transaction | VersionedTransaction): Promise<Transaction | VersionedTransaction>;
|
|
9
|
+
/**
|
|
10
|
+
* Signs and submits a Solana transaction to the network.
|
|
11
|
+
*
|
|
12
|
+
* This method handles blockhash and transaction confirmation automatically - you do NOT need to
|
|
13
|
+
* set recentBlockhash or lastValidBlockHeight on the transaction before calling this method.
|
|
14
|
+
* The network/RPC URL is derived from the provider's configuration (set during initialization).
|
|
15
|
+
*
|
|
16
|
+
* @param transaction - The transaction to sign and submit (Transaction or VersionedTransaction)
|
|
17
|
+
* @param feePayer - Optional fee payer public key. If not provided and the transaction doesn't
|
|
18
|
+
* already have a feePayer set, the connected wallet address will be used.
|
|
19
|
+
* Useful for co-signing scenarios where a different account pays the fees.
|
|
20
|
+
* @returns The transaction signature
|
|
21
|
+
*/
|
|
22
|
+
signAndSubmitTransaction(transaction: Transaction | VersionedTransaction, feePayer?: PublicKey): Promise<string>;
|
|
23
|
+
restoreSession(): Promise<User | null>;
|
|
24
|
+
logout(): Promise<void>;
|
|
25
|
+
getNativeMethods(): Promise<any>;
|
|
26
|
+
}
|
|
27
|
+
export interface User {
|
|
28
|
+
/**
|
|
29
|
+
* Universal stable identity of the user (resolves @user.id). For wallet/SIWS
|
|
30
|
+
* logins this EQUALS `address`; for email/social (Bounded Better Auth) logins
|
|
31
|
+
* it is the account identity (and `address` may be null). Derived from the
|
|
32
|
+
* idToken's `custom:userId` claim, falling back to `custom:walletAddress` for
|
|
33
|
+
* tokens minted before the claim-split. Used for ownership/membership/identity.
|
|
34
|
+
*
|
|
35
|
+
* Optional for backwards compatibility: existing apps that only read
|
|
36
|
+
* `user.address` keep working unchanged. New code should prefer `user.id` as
|
|
37
|
+
* the principal. Always present for a session derived from a real idToken;
|
|
38
|
+
* may be undefined only for legacy/manually-constructed User objects.
|
|
39
|
+
*/
|
|
40
|
+
id?: string;
|
|
41
|
+
/**
|
|
42
|
+
* REAL onchain wallet address. Present for wallet/SIWS logins; `null` for
|
|
43
|
+
* email-only logins (which have no wallet until they link one). Kept for
|
|
44
|
+
* backwards compatibility — for wallet users `id === address`.
|
|
45
|
+
*/
|
|
46
|
+
address: string;
|
|
47
|
+
/**
|
|
48
|
+
* Verified, lowercased email of the user — present only for email-login
|
|
49
|
+
* (Bounded Better Auth) sessions; `null`/absent for wallet/SIWS sessions.
|
|
50
|
+
* Resolves @user.email in offchain policies.
|
|
51
|
+
*/
|
|
52
|
+
email?: string | null;
|
|
53
|
+
/**
|
|
54
|
+
* True when this is a zero-friction GUEST (anonymous) session created via
|
|
55
|
+
* `signInAnonymously()` — a durable device-keypair identity that owns data
|
|
56
|
+
* but has no email/real credential yet. Mirrors Firebase's `user.isAnonymous`
|
|
57
|
+
* / Supabase's `is_anonymous`. Flips to `false` once the guest is upgraded
|
|
58
|
+
* (links an email/social credential), with `id` preserved across the upgrade.
|
|
59
|
+
* Apps use this to decide whether to show an "upgrade / save your account"
|
|
60
|
+
* prompt. `false`/absent for real (email/social/wallet) logins.
|
|
61
|
+
*/
|
|
62
|
+
isAnonymous?: boolean;
|
|
63
|
+
provider: AuthProvider;
|
|
64
|
+
}
|
|
65
|
+
export interface EVMTransaction {
|
|
66
|
+
contractAddress: string;
|
|
67
|
+
contractAbi: string | any;
|
|
68
|
+
functionName: string;
|
|
69
|
+
value: string;
|
|
70
|
+
txArgs: any[];
|
|
71
|
+
}
|
|
72
|
+
export interface SolTransaction {
|
|
73
|
+
appId: string;
|
|
74
|
+
txArgs: any[];
|
|
75
|
+
lutKey: PublicKey | null;
|
|
76
|
+
/** Complete set of LUT addresses to use (includes lutKey when present). When provided, takes precedence over lutKey. */
|
|
77
|
+
additionalLutAddresses?: string[];
|
|
78
|
+
network: string;
|
|
79
|
+
preInstructions: TransactionInstruction[];
|
|
80
|
+
/** Base64-encoded VersionedTransaction prebuilt server-side for sponsorship and/or required co-signers. */
|
|
81
|
+
signedTransaction?: string;
|
|
82
|
+
}
|
|
83
|
+
export interface TransactionResult {
|
|
84
|
+
transactionSignature?: any;
|
|
85
|
+
signedTransaction?: any;
|
|
86
|
+
blockNumber: number;
|
|
87
|
+
gasUsed: string;
|
|
88
|
+
data?: any;
|
|
89
|
+
}
|
|
90
|
+
export interface TransactionReceipt {
|
|
91
|
+
}
|
|
92
|
+
export interface SubscriptionOptions {
|
|
93
|
+
/**
|
|
94
|
+
* Structured MongoDB-style filter (same shape as GetOptions.filter), e.g.
|
|
95
|
+
* `{ status: "open", amount: { $gt: 10 } }`. Deterministic; the live feed only
|
|
96
|
+
* delivers documents matching the filter (and obeying the read rule).
|
|
97
|
+
*/
|
|
98
|
+
filter?: Record<string, any>;
|
|
99
|
+
/**
|
|
100
|
+
* Sort spec applied server-side to the live feed (same shape/semantics as
|
|
101
|
+
* GetOptions.sort), e.g. `{ createdAt: -1 }` (1 = asc, -1 = desc). The server
|
|
102
|
+
* sorts the read-authorized result set before delivering it.
|
|
103
|
+
*/
|
|
104
|
+
sort?: Record<string, number>;
|
|
105
|
+
prompt?: string;
|
|
106
|
+
/**
|
|
107
|
+
* Include documents from sub-paths (nested collections) in the live feed, same
|
|
108
|
+
* as GetOptions.includeSubPaths. The server applies it to both initial data and
|
|
109
|
+
* deltas.
|
|
110
|
+
*/
|
|
111
|
+
includeSubPaths?: boolean;
|
|
112
|
+
/** Relationship shape for joined data (e.g., { owner: {}, posts: { comments: {} } }) */
|
|
113
|
+
shape?: Record<string, any>;
|
|
114
|
+
/** Maximum number of items to return (opt-in pagination) */
|
|
115
|
+
limit?: number;
|
|
116
|
+
/** Opaque cursor for cursor-based pagination (used with limit) */
|
|
117
|
+
cursor?: string;
|
|
118
|
+
/** Override the app ID for this subscription (instead of the configured default) */
|
|
119
|
+
appId?: string;
|
|
120
|
+
onData?: (data: any) => void;
|
|
121
|
+
onError?: (error: any) => void;
|
|
122
|
+
/**
|
|
123
|
+
* @internal Per-subscription auth override. The server `WalletClient` sets this
|
|
124
|
+
* (via `subscribe()`) so the WS connection authenticates as that wallet's
|
|
125
|
+
* identity instead of the ambient `BOUNDED_PRIVATE_KEY` env keypair. Mirrors
|
|
126
|
+
* `RequestOverrides`; only the fields the subscribe path consumes. App code
|
|
127
|
+
* never sets this — it's threaded internally.
|
|
128
|
+
*/
|
|
129
|
+
_overrides?: {
|
|
130
|
+
_getAuthHeaders?: () => Promise<Record<string, string>>;
|
|
131
|
+
_walletAddress?: string;
|
|
132
|
+
_clearAuth?: () => Promise<void>;
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
export type TransactionOptions = {
|
|
136
|
+
shouldSubmit?: boolean;
|
|
137
|
+
};
|
|
138
|
+
export interface OffchainInstruction {
|
|
139
|
+
type: 'set' | 'delete';
|
|
140
|
+
path: string;
|
|
141
|
+
data?: Record<string, any>;
|
|
142
|
+
}
|
|
143
|
+
export interface OffchainTransaction {
|
|
144
|
+
id: string;
|
|
145
|
+
version: 1;
|
|
146
|
+
feePayer: string;
|
|
147
|
+
instructions: OffchainInstruction[];
|
|
148
|
+
message: string;
|
|
149
|
+
createdAt: number;
|
|
150
|
+
expiresAt: number;
|
|
151
|
+
appId: string;
|
|
152
|
+
nonce: string;
|
|
153
|
+
}
|
|
154
|
+
export interface SignedOffchainTransaction {
|
|
155
|
+
transaction: OffchainTransaction;
|
|
156
|
+
signature: string;
|
|
157
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Window {
|
|
3
|
+
CUSTOM_TAROBASE_APP_ID_HEADER?: string;
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
export declare function makeApiRequest(method: string, urlPath: string, data?: any, _overrides?: {
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
_getAuthHeaders?: () => Promise<Record<string, string>>;
|
|
9
|
+
_clearAuth?: () => Promise<void>;
|
|
10
|
+
timeout?: number;
|
|
11
|
+
}): Promise<any>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function genNonce(): Promise<any>;
|
|
2
|
+
export declare function genAuthNonce(): Promise<any>;
|
|
3
|
+
export declare function createSessionWithSignature(address: string, message: string, signature: string): Promise<any>;
|
|
4
|
+
export declare function refreshSession(refreshToken: string, issuer?: string): Promise<any>;
|
|
5
|
+
/**
|
|
6
|
+
* Revoke a session's refresh-token family server-side (logout). Best-effort: if the
|
|
7
|
+
* call fails the local logout still proceeds. Routes to the minting issuer.
|
|
8
|
+
*/
|
|
9
|
+
export declare function revokeSession(refreshToken: string, issuer?: string): Promise<void>;
|
|
10
|
+
export declare function signSessionCreateMessage(_signMessageFunction: (message: string) => Promise<string>): Promise<void>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe base64 helpers for tarobase-core.
|
|
3
|
+
*
|
|
4
|
+
* Uses the global atob/btoa when available (browser, RN with polyfill),
|
|
5
|
+
* falls back to the 'buffer' package (Node.js / SSR / RN without polyfill).
|
|
6
|
+
*
|
|
7
|
+
* These are used instead of bare `atob()`/`btoa()` so the core package
|
|
8
|
+
* works in React Native without requiring the consumer to polyfill globals.
|
|
9
|
+
*/
|
|
10
|
+
export declare function safeAtob(input: string): string;
|
|
11
|
+
export declare function safeBtoa(input: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Decode a base64url-encoded string (used by JWT payloads).
|
|
14
|
+
* Normalises base64url → standard base64 before decoding.
|
|
15
|
+
*/
|
|
16
|
+
export declare function decodeBase64Url(input: string): string;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session manager for React Native environments.
|
|
3
|
+
*
|
|
4
|
+
* Drop-in replacement for WebSessionManager that uses a pluggable
|
|
5
|
+
* StorageAdapter instead of browser localStorage, and a pluggable
|
|
6
|
+
* base64-decode instead of the browser's atob().
|
|
7
|
+
*
|
|
8
|
+
* Consumers must call ReactNativeSessionManager.configure() once at
|
|
9
|
+
* startup to supply these adapters (e.g. MMKV, AsyncStorage wrapper,
|
|
10
|
+
* base64 polyfill).
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Synchronous storage adapter for React Native session persistence.
|
|
14
|
+
*
|
|
15
|
+
* **Security: tokens (access, identity, refresh) are stored as plaintext JSON.**
|
|
16
|
+
* Use an encrypted storage backend in production — for example:
|
|
17
|
+
* - MMKV with an encryption key (`new MMKV({ encryptionKey: '...' })`)
|
|
18
|
+
* - expo-secure-store
|
|
19
|
+
* - react-native-keychain
|
|
20
|
+
*
|
|
21
|
+
* Plaintext token storage on a rooted/jailbroken device is a credential theft risk.
|
|
22
|
+
*/
|
|
23
|
+
export interface RNStorageAdapter {
|
|
24
|
+
getItem(key: string): string | null;
|
|
25
|
+
setItem(key: string, value: string): void;
|
|
26
|
+
removeItem(key: string): void;
|
|
27
|
+
}
|
|
28
|
+
interface RNSessionConfig {
|
|
29
|
+
storage: RNStorageAdapter;
|
|
30
|
+
/** base64 → binary string (replaces browser atob). */
|
|
31
|
+
atob: (input: string) => string;
|
|
32
|
+
}
|
|
33
|
+
export declare class ReactNativeSessionManager {
|
|
34
|
+
private static TAROBASE_SESSION_STORAGE_KEY;
|
|
35
|
+
/**
|
|
36
|
+
* Must be called once before any other method.
|
|
37
|
+
*
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { ReactNativeSessionManager } from '@bounded-sh/core';
|
|
40
|
+
* import { MMKV } from 'react-native-mmkv';
|
|
41
|
+
* import { decode } from 'base-64';
|
|
42
|
+
*
|
|
43
|
+
* const mmkv = new MMKV();
|
|
44
|
+
* ReactNativeSessionManager.configure({
|
|
45
|
+
* storage: {
|
|
46
|
+
* getItem: (k) => mmkv.getString(k) ?? null,
|
|
47
|
+
* setItem: (k, v) => mmkv.set(k, v),
|
|
48
|
+
* removeItem: (k) => mmkv.delete(k),
|
|
49
|
+
* },
|
|
50
|
+
* atob: decode,
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
static configure(cfg: RNSessionConfig): void;
|
|
55
|
+
/**
|
|
56
|
+
* Whether configure() has been called. This is the canonical "are we on
|
|
57
|
+
* React Native?" signal used by getActiveSessionManager(): RN consumers MUST
|
|
58
|
+
* call configure() at startup, while web/Node never do. Far more reliable
|
|
59
|
+
* than sniffing `typeof window` (React Native defines a global `window`, so
|
|
60
|
+
* that test misclassifies RN as web and routes session writes to a
|
|
61
|
+
* non-existent localStorage).
|
|
62
|
+
*/
|
|
63
|
+
static isConfigured(): boolean;
|
|
64
|
+
private static getStorage;
|
|
65
|
+
private static decodeBase64;
|
|
66
|
+
/**
|
|
67
|
+
* Decode a base64url-encoded string (used by JWT payloads).
|
|
68
|
+
* Normalises base64url → standard base64 before decoding.
|
|
69
|
+
*/
|
|
70
|
+
private static decodeBase64Url;
|
|
71
|
+
static storeSession(address: string, accessToken: string, idToken: string, refreshToken: string, issuer?: string): Promise<void>;
|
|
72
|
+
static getSession(): Promise<{
|
|
73
|
+
address: string;
|
|
74
|
+
session: any;
|
|
75
|
+
} | null>;
|
|
76
|
+
static clearSession(): void;
|
|
77
|
+
static isAuthenticated(): boolean;
|
|
78
|
+
static getIdToken(): string | null;
|
|
79
|
+
/** The issuer base that minted this session (for routing silent refresh). */
|
|
80
|
+
static getIssuer(): string | null;
|
|
81
|
+
static getRefreshToken(): string | null;
|
|
82
|
+
static updateIdTokenAndAccessToken(idToken: string, accessToken: string, refreshToken?: string): Promise<void>;
|
|
83
|
+
}
|
|
84
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Keypair } from "@solana/web3.js";
|
|
2
|
+
/**
|
|
3
|
+
* Server-side SessionManager
|
|
4
|
+
* --------------------------
|
|
5
|
+
* • Default singleton via `ServerSessionManager.instance` (reads keypair from env)
|
|
6
|
+
* • Per-keypair instances via `ServerSessionManager.forKeypair(kp)`
|
|
7
|
+
* • Keeps session data in-memory for the life of the instance
|
|
8
|
+
* • If `getSession()` finds no cached session it calls `createSession()`
|
|
9
|
+
* to obtain fresh tokens.
|
|
10
|
+
*/
|
|
11
|
+
export interface ServerSession {
|
|
12
|
+
address: string;
|
|
13
|
+
accessToken: string;
|
|
14
|
+
idToken: string;
|
|
15
|
+
refreshToken: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class ServerSessionManager {
|
|
18
|
+
static readonly instance: ServerSessionManager;
|
|
19
|
+
private session;
|
|
20
|
+
private pendingSession;
|
|
21
|
+
private readonly keypair;
|
|
22
|
+
private constructor();
|
|
23
|
+
/**
|
|
24
|
+
* Create a session manager for a specific keypair.
|
|
25
|
+
* Each instance has its own independent session cache.
|
|
26
|
+
*/
|
|
27
|
+
static forKeypair(keypair: Keypair): ServerSessionManager;
|
|
28
|
+
private createSession;
|
|
29
|
+
getSession(): Promise<ServerSession>;
|
|
30
|
+
setSession(session: ServerSession): void;
|
|
31
|
+
clearSession(): void;
|
|
32
|
+
isAuthenticated(): boolean;
|
|
33
|
+
getIdToken(): string | null;
|
|
34
|
+
getRefreshToken(): string | null;
|
|
35
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { WebSessionManager } from './web-session-manager';
|
|
2
|
+
/**
|
|
3
|
+
* The shared static shape of both client session managers. WebSessionManager
|
|
4
|
+
* (localStorage) and ReactNativeSessionManager (pluggable StorageAdapter) expose
|
|
5
|
+
* an identical static API over the SAME storage key, so either one is a drop-in
|
|
6
|
+
* for the other.
|
|
7
|
+
*/
|
|
8
|
+
export type ClientSessionManager = typeof WebSessionManager;
|
|
9
|
+
/**
|
|
10
|
+
* Return the active CLIENT session manager for the current runtime.
|
|
11
|
+
*
|
|
12
|
+
* This is the single source of truth for "which store holds the session token"
|
|
13
|
+
* and MUST be used everywhere the client reads/writes the session (login,
|
|
14
|
+
* restore, logout, and — critically — the per-request auth-header path in
|
|
15
|
+
* utils.ts). Previously this decision was made ad-hoc with
|
|
16
|
+
* `typeof window !== 'undefined' ? WebSessionManager : ReactNativeSessionManager`,
|
|
17
|
+
* which is wrong on React Native: RN defines a global `window`, so that test
|
|
18
|
+
* picked WebSessionManager and then hit a non-existent `localStorage` — the
|
|
19
|
+
* session was silently dropped (or threw), so every authenticated request 403'd.
|
|
20
|
+
*
|
|
21
|
+
* Decision rule: if a consumer configured the React Native session manager
|
|
22
|
+
* (ReactNativeSessionManager.configure(), which RN apps call once at startup and
|
|
23
|
+
* web/Node never do), we're on RN — use it. Otherwise use the localStorage-backed
|
|
24
|
+
* WebSessionManager (which itself no-ops gracefully in Node/SSR where there is no
|
|
25
|
+
* `window`). This changes ONLY React Native behavior; web and Node are unchanged.
|
|
26
|
+
*
|
|
27
|
+
* NOTE: this intentionally does NOT cover the SERVER (keypair) path — callers that
|
|
28
|
+
* branch on `isServer` keep using ServerSessionManager and only fall through to
|
|
29
|
+
* getActiveSessionManager() for the browser/RN client case.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getActiveSessionManager(): ClientSessionManager;
|