@bounded-sh/server 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 +269 -0
- package/dist/auth/index.d.ts +6 -0
- package/dist/auth/providers/offchain-auth-provider.d.ts +26 -0
- package/dist/auth/providers/solana-keypair-provider.d.ts +40 -0
- package/dist/global.d.ts +2 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +1058 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +919 -0
- package/dist/index.mjs.map +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/wallet-client.d.ts +81 -0
- package/dist/webhooks.d.ts +89 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# @tarobase/server
|
|
2
|
+
|
|
3
|
+
Server SDK for Tarobase API - Node.js/Backend implementation. This package provides functionality for server-side applications to interact with the Tarobase API using Solana keypairs for authentication.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @tarobase/server
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or using yarn:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
yarn add @tarobase/server
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- Server-side authentication using Solana keypairs
|
|
20
|
+
- In-memory session management (no cookies or local storage required)
|
|
21
|
+
- Support for all Tarobase data operations (get, getMany, set, query)
|
|
22
|
+
- Real-time subscriptions
|
|
23
|
+
- Transaction signing and execution
|
|
24
|
+
- TypeScript support
|
|
25
|
+
|
|
26
|
+
## Basic Usage
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { init, login, getCurrentUser, set, get } from '@tarobase/server';
|
|
30
|
+
import { Keypair } from '@solana/web3.js';
|
|
31
|
+
|
|
32
|
+
async function main() {
|
|
33
|
+
// Initialize the SDK
|
|
34
|
+
await init({
|
|
35
|
+
apiKey: 'your-api-key',
|
|
36
|
+
appId: 'your-app-id',
|
|
37
|
+
authMethod: 'solana-keypair'
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Create or load a Solana keypair
|
|
41
|
+
const keypair = Keypair.generate(); // or load from a file/secret
|
|
42
|
+
// Alternative: const keypair = "your-base58-encoded-private-key"
|
|
43
|
+
|
|
44
|
+
// Log in with the keypair
|
|
45
|
+
const user = await login(keypair);
|
|
46
|
+
if (!user) {
|
|
47
|
+
console.error('Login failed');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log(`Logged in as: ${user.address}`);
|
|
52
|
+
|
|
53
|
+
// Set data
|
|
54
|
+
await set('todos/123', {
|
|
55
|
+
text: 'Buy milk',
|
|
56
|
+
completed: false,
|
|
57
|
+
created: new Date().toISOString()
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Get data
|
|
61
|
+
const todo = await get('todos/123');
|
|
62
|
+
console.log('Retrieved todo:', todo);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
main().catch(console.error);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Advanced Usage
|
|
69
|
+
|
|
70
|
+
### Loading a Keypair from a Secret Key File
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { init, login, getCurrentUser } from '@tarobase/server';
|
|
74
|
+
import { Keypair } from '@solana/web3.js';
|
|
75
|
+
import * as fs from 'fs';
|
|
76
|
+
|
|
77
|
+
// Load keypair from file
|
|
78
|
+
const secretKeyString = fs.readFileSync('/path/to/keypair.json', 'utf8');
|
|
79
|
+
const secretKey = Uint8Array.from(JSON.parse(secretKeyString));
|
|
80
|
+
const keypair = Keypair.fromSecretKey(secretKey);
|
|
81
|
+
|
|
82
|
+
// Initialize and login
|
|
83
|
+
await init({ apiKey: 'your-api-key', appId: 'your-app-id' });
|
|
84
|
+
await login(keypair);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Using the SolanaKeypairProvider Directly
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { init, SolanaKeypairProvider, getAuthProvider } from '@tarobase/server';
|
|
91
|
+
import { Keypair } from '@solana/web3.js';
|
|
92
|
+
|
|
93
|
+
// Initialize the SDK
|
|
94
|
+
await init({
|
|
95
|
+
apiKey: 'your-api-key',
|
|
96
|
+
appId: 'your-app-id',
|
|
97
|
+
rpcUrl: 'https://api.mainnet-beta.solana.com'
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Get the auth provider (automatically created during init)
|
|
101
|
+
const provider = await getAuthProvider() as SolanaKeypairProvider;
|
|
102
|
+
|
|
103
|
+
// Or create a provider instance directly
|
|
104
|
+
// const provider = new SolanaKeypairProvider("https://api.mainnet-beta.solana.com");
|
|
105
|
+
|
|
106
|
+
// Set the keypair
|
|
107
|
+
provider.setKeypair(Keypair.generate());
|
|
108
|
+
|
|
109
|
+
// Login
|
|
110
|
+
const user = await provider.login();
|
|
111
|
+
|
|
112
|
+
// Sign a message
|
|
113
|
+
const signature = await provider.signMessage("Hello, world!");
|
|
114
|
+
|
|
115
|
+
// Run a transaction (example)
|
|
116
|
+
const txResult = await provider.runTransaction(undefined, {
|
|
117
|
+
appId: 'your-app-id',
|
|
118
|
+
txArgs: [{
|
|
119
|
+
setDocumentData: [{ path: 'todos/123', data: { text: 'New todo' } }],
|
|
120
|
+
deletePaths: [],
|
|
121
|
+
remainingAccounts: [],
|
|
122
|
+
idl: {}
|
|
123
|
+
}]
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Subscriptions
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { init, login, subscribe, unsubscribe } from '@tarobase/server';
|
|
131
|
+
import { Keypair } from '@solana/web3.js';
|
|
132
|
+
|
|
133
|
+
// Initialize and login
|
|
134
|
+
await init({ apiKey: 'your-api-key', appId: 'your-app-id' });
|
|
135
|
+
await login(Keypair.generate());
|
|
136
|
+
|
|
137
|
+
// Subscribe to changes
|
|
138
|
+
const unsubscribeFunc = await subscribe('todos', (data) => {
|
|
139
|
+
console.log('Todos updated:', data);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Later, unsubscribe when done
|
|
143
|
+
unsubscribeFunc();
|
|
144
|
+
// Or use the unsubscribe function
|
|
145
|
+
await unsubscribe('todos');
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## API Reference
|
|
149
|
+
|
|
150
|
+
### Configuration and Initialization
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
function init(config: Partial<ClientConfig>): Promise<void>;
|
|
154
|
+
function getConfig(): Promise<ClientConfig>;
|
|
155
|
+
function getSessionOptions(): SessionOptions;
|
|
156
|
+
function isInitialized(): boolean;
|
|
157
|
+
function waitForInitialization(): Promise<void>;
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Authentication
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
function login(keypair?: Keypair | string | Uint8Array): Promise<User | null>;
|
|
164
|
+
function logout(): Promise<void>;
|
|
165
|
+
function getCurrentUser(): User | null;
|
|
166
|
+
function getAuthProvider(): Promise<AuthProvider>;
|
|
167
|
+
function getIdToken(): Promise<string | null>;
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Data Operations
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
function get(path: string): Promise<any>;
|
|
174
|
+
function getMany(paths: string[], options?: { bypassCache?: boolean }): Promise<GetManyResult[]>;
|
|
175
|
+
function set(path: string, data: any, options?: SetOptions): Promise<any>;
|
|
176
|
+
function setMany(paths: { [key: string]: any }, options?: SetOptions): Promise<any>;
|
|
177
|
+
function setFile(path: string, file: File, metadata?: any): Promise<any>;
|
|
178
|
+
function getFiles(path: string): Promise<any>;
|
|
179
|
+
function runQuery(queryString: string, variables?: any): Promise<any>;
|
|
180
|
+
function runQueryMany(queryString: string, variables?: any): Promise<any>;
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Subscriptions
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
function subscribe(path: string, callback: (data: any) => void): Promise<() => void>;
|
|
187
|
+
function unsubscribe(path: string): Promise<void>;
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Solana Keypair Provider
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
class SolanaKeypairProvider implements AuthProvider {
|
|
194
|
+
constructor(networkUrl?: string);
|
|
195
|
+
|
|
196
|
+
setKeypair(keypair: Keypair | string | Uint8Array): void;
|
|
197
|
+
login(): Promise<User | null>;
|
|
198
|
+
logout(): Promise<void>;
|
|
199
|
+
signMessage(message: string): Promise<string>;
|
|
200
|
+
runTransaction(evmTransactionData?: EVMTransaction, solTransactionData?: SolTransaction, options?: SetOptions): Promise<TransactionResult>;
|
|
201
|
+
restoreSession(): Promise<User | null>;
|
|
202
|
+
getNativeMethods(): Promise<any>;
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Types
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
interface ClientConfig {
|
|
210
|
+
apiKey: string;
|
|
211
|
+
authMethod: 'solana-keypair' | string;
|
|
212
|
+
wsApiUrl: string;
|
|
213
|
+
apiUrl: string;
|
|
214
|
+
appId: string;
|
|
215
|
+
authApiUrl: string;
|
|
216
|
+
chain: string;
|
|
217
|
+
rpcUrl: string;
|
|
218
|
+
skipBackendInit: boolean;
|
|
219
|
+
useSessionStorage: boolean;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
interface User {
|
|
223
|
+
address: string;
|
|
224
|
+
provider: AuthProvider;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
interface SetOptions {
|
|
228
|
+
shouldSubmitTx?: boolean;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
interface GetManyResult {
|
|
232
|
+
path: string;
|
|
233
|
+
data: any | null;
|
|
234
|
+
error?: {
|
|
235
|
+
code: 'NOT_FOUND' | 'UNAUTHORIZED' | 'INVALID_PATH';
|
|
236
|
+
message: string;
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
interface TransactionResult {
|
|
241
|
+
transactionSignature?: string;
|
|
242
|
+
signedTransaction?: any;
|
|
243
|
+
blockNumber: number;
|
|
244
|
+
gasUsed: string;
|
|
245
|
+
data: any;
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Contributing
|
|
250
|
+
|
|
251
|
+
Please see the main repository for contribution guidelines.
|
|
252
|
+
|
|
253
|
+
## Key Differences from the Web SDK
|
|
254
|
+
|
|
255
|
+
This server-side SDK differs from the web SDK in several important ways:
|
|
256
|
+
|
|
257
|
+
1. **Authentication Method**: Uses Solana keypairs instead of browser wallets
|
|
258
|
+
2. **Storage Strategy**: Uses in-memory storage instead of localStorage/sessionStorage
|
|
259
|
+
3. **Environment**: Optimized for Node.js/backend environments rather than browsers
|
|
260
|
+
4. **Session Management**: Does not rely on browser-specific APIs
|
|
261
|
+
5. **Dependencies**: Excludes browser-specific libraries
|
|
262
|
+
|
|
263
|
+
## Part of the Tarobase SDK Family
|
|
264
|
+
|
|
265
|
+
This package is part of a family of modular SDKs:
|
|
266
|
+
|
|
267
|
+
- **@pooflabs/core**: Core functionality shared between all SDKs
|
|
268
|
+
- **@pooflabs/web**: Browser-focused SDK (identical to original js-sdk)
|
|
269
|
+
- **@pooflabs/server**: Server-side SDK for backend applications
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AuthProvider } from '@bounded-sh/core';
|
|
2
|
+
export declare const SOLANA_DEVNET_RPC_URL = "https://idelle-8nxsep-fast-devnet.helius-rpc.com";
|
|
3
|
+
export declare const SOLANA_MAINNET_RPC_URL = "https://celestia-cegncv-fast-mainnet.helius-rpc.com";
|
|
4
|
+
export declare const SURFNET_RPC_URL = "https://surfpool.fly.dev";
|
|
5
|
+
export declare function getAuthProvider(): Promise<AuthProvider>;
|
|
6
|
+
export declare function matchAuthProvider(rpcUrl: string | null): Promise<AuthProvider>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AuthProvider } from '@bounded-sh/core';
|
|
2
|
+
import { Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
3
|
+
/**
|
|
4
|
+
* Server-side OffchainAuthProvider wrapper for the poofnet environment.
|
|
5
|
+
*
|
|
6
|
+
* For signMessage, this generates a mock signature using SHA-256 hashing.
|
|
7
|
+
* This is used for offchain transaction signing.
|
|
8
|
+
*/
|
|
9
|
+
export declare class OffchainAuthProvider implements AuthProvider {
|
|
10
|
+
private wrappedProvider;
|
|
11
|
+
constructor(wrappedProvider: AuthProvider);
|
|
12
|
+
login(): Promise<any>;
|
|
13
|
+
logout(): Promise<void>;
|
|
14
|
+
restoreSession(): Promise<any>;
|
|
15
|
+
getNativeMethods(): Promise<any>;
|
|
16
|
+
signMessage(message: string): Promise<string>;
|
|
17
|
+
signMessageMock(message: string): Promise<string>;
|
|
18
|
+
signTransaction(transaction: Transaction | VersionedTransaction): Promise<Transaction | VersionedTransaction>;
|
|
19
|
+
/**
|
|
20
|
+
* Sign and submit transaction - not supported in poofnet environment.
|
|
21
|
+
* See the real providers (PhantomWalletProvider, PrivyWalletProvider, SolanaKeypairProvider)
|
|
22
|
+
* for the full implementation with blockhash handling and feePayer support.
|
|
23
|
+
*/
|
|
24
|
+
signAndSubmitTransaction(_transaction: Transaction | VersionedTransaction, _feePayer?: any): Promise<string>;
|
|
25
|
+
runTransaction(evmTransactionData?: any, solTransactionData?: any, options?: any): Promise<any>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Keypair, Transaction, VersionedTransaction } from '@solana/web3.js';
|
|
2
|
+
import * as anchor from '@coral-xyz/anchor';
|
|
3
|
+
import type { AuthProvider, EVMTransaction, SolTransaction, TransactionResult, User, SetOptions } from '@bounded-sh/core';
|
|
4
|
+
export declare class SolanaKeypairProvider implements AuthProvider {
|
|
5
|
+
private readonly networkUrl;
|
|
6
|
+
private explicitKeypair?;
|
|
7
|
+
private cachedKeypair?;
|
|
8
|
+
constructor(networkUrl?: string | null, keypair?: Keypair);
|
|
9
|
+
private get keypair();
|
|
10
|
+
login(): Promise<User | null>;
|
|
11
|
+
restoreSession(): Promise<User | null>;
|
|
12
|
+
logout(): Promise<void>;
|
|
13
|
+
signMessage(message: string): Promise<string>;
|
|
14
|
+
signTransaction(transaction: Transaction | VersionedTransaction): Promise<Transaction | VersionedTransaction>;
|
|
15
|
+
/**
|
|
16
|
+
* Signs and submits a Solana transaction to the network.
|
|
17
|
+
*
|
|
18
|
+
* This method handles blockhash and transaction confirmation automatically - you do NOT need to
|
|
19
|
+
* set recentBlockhash or lastValidBlockHeight on the transaction before calling this method.
|
|
20
|
+
* The network/RPC URL is derived from the provider's configuration (set during initialization).
|
|
21
|
+
*
|
|
22
|
+
* @param transaction - The transaction to sign and submit (Transaction or VersionedTransaction)
|
|
23
|
+
* @param feePayer - Optional fee payer public key. If not provided and the transaction doesn't
|
|
24
|
+
* already have a feePayer set, the keypair's public key will be used.
|
|
25
|
+
* Useful for co-signing scenarios where a different account pays the fees.
|
|
26
|
+
* @returns The transaction signature
|
|
27
|
+
*/
|
|
28
|
+
signAndSubmitTransaction(transaction: Transaction | VersionedTransaction, feePayer?: anchor.web3.PublicKey): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Submits a signed transaction and waits for confirmation using polling.
|
|
31
|
+
* Shared by both signAndSubmitTransaction and runTransactionInner.
|
|
32
|
+
*/
|
|
33
|
+
private submitAndConfirmTransaction;
|
|
34
|
+
private getRpcUrl;
|
|
35
|
+
runTransaction(_evm?: EVMTransaction, sol?: SolTransaction, opts?: SetOptions): Promise<TransactionResult>;
|
|
36
|
+
private runTransactionInner;
|
|
37
|
+
getNativeMethods(): Promise<{
|
|
38
|
+
keypair: Keypair;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
package/dist/global.d.ts
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { init } from "./global";
|
|
2
|
+
export { getConfig } from '@bounded-sh/core';
|
|
3
|
+
export { getAuthProvider } from './auth';
|
|
4
|
+
export { get, getMany, set, setMany, setFile, getFiles, search, queryAggregate, runQuery, runQueryMany, runExpression, runExpressionMany, signMessage, signTransaction, signAndSubmitTransaction, count, aggregate, InsufficientBalanceError } from '@bounded-sh/core';
|
|
5
|
+
export type { GetOptions, SearchOptions, SetOptions, CountOptions, AggregateOptions, AggregateOperation, AggregateResult, AggregateSpec, AggregateRow, QueryAggregateOptions, GetManyResult, RunExpressionOptions, RunExpressionResult, RequestOverrides, RunQueryOptions } from '@bounded-sh/core';
|
|
6
|
+
export { subscribe } from '@bounded-sh/core';
|
|
7
|
+
export { functions, invokeFunction, FunctionInvokeError } from '@bounded-sh/core';
|
|
8
|
+
export type { InvokeOptions } from '@bounded-sh/core';
|
|
9
|
+
export { live, liveIntent, LiveIntentError } from '@bounded-sh/core';
|
|
10
|
+
export type { LiveIntentOptions } from '@bounded-sh/core';
|
|
11
|
+
export * from '@bounded-sh/core';
|
|
12
|
+
export { getIdToken } from './utils';
|
|
13
|
+
export { createWalletClient, WalletClient } from './wallet-client';
|
|
14
|
+
export type { CreateWalletClientOptions } from './wallet-client';
|
|
15
|
+
export { verifyWebhook, clearWebhookKeyCache, WebhookVerificationError, DEFAULT_WEBHOOK_KEYS_URL, InMemoryReplayStore } from './webhooks';
|
|
16
|
+
export type { WebhookPayload, WebhookPublicKey, WebhookOperation, VerifyWebhookOptions, WebhookHeaders, WebhookReplayStore } from './webhooks';
|