@tuwaio/quasar-sdk 0.1.2 → 0.1.4
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 +67 -37
- package/package.json +16 -9
package/README.md
CHANGED
|
@@ -31,10 +31,10 @@ It operates strictly on the server (Node.js, Next.js Server Actions, or Edge fun
|
|
|
31
31
|
## 💾 Installation
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
pnpm add @tuwaio/quasar-sdk ofetch @tuwaio/pulsar-core
|
|
34
|
+
pnpm add @tuwaio/quasar-sdk ofetch @tuwaio/pulsar-core @tuwaio/siwx-core @tuwaio/siwx-server @tuwaio/siwx-react
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
_Note: `ofetch` and `@tuwaio/pulsar-core` are required
|
|
37
|
+
_Note: `ofetch` and `@tuwaio/pulsar-core` are required peer dependencies. The `@tuwaio/siwx-*` packages are required if you intend to use the headless SIWX (CAIP-122) authentication integrations._
|
|
38
38
|
|
|
39
39
|
---
|
|
40
40
|
|
|
@@ -43,9 +43,11 @@ _Note: `ofetch` and `@tuwaio/pulsar-core` are required as peer dependencies to e
|
|
|
43
43
|
This is a basic example of how to interact with the Quasar Cloud directly from your secure backend environments (like Next.js API Routes, Server Actions, or NestJS).
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
import
|
|
46
|
+
import { cookies } from 'next/headers';
|
|
47
|
+
import { Quasar, type Transaction } from '@tuwaio/quasar-sdk';
|
|
48
|
+
import { isSessionMatchingTarget } from '@tuwaio/sdk/siwx';
|
|
49
|
+
import { getSiwxServerSession } from '@tuwaio/sdk/siwx/server';
|
|
50
|
+
import { sessionStore } from '@/lib/authStores';
|
|
49
51
|
|
|
50
52
|
// Initialize Quasar with your Secret Key from the Dashboard
|
|
51
53
|
const quasar = new Quasar({ secretKey: process.env.QUASAR_SDK_SK ?? '' });
|
|
@@ -53,12 +55,19 @@ const quasar = new Quasar({ secretKey: process.env.QUASAR_SDK_SK ?? '' });
|
|
|
53
55
|
/**
|
|
54
56
|
* Example Next.js Server Action to Sync a Transaction
|
|
55
57
|
*/
|
|
56
|
-
export async function syncTransaction(tx: Transaction
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
export async function syncTransaction(tx: Transaction) {
|
|
59
|
+
const session = await getSiwxServerSession({
|
|
60
|
+
cookieSource: await cookies(),
|
|
61
|
+
sessionStore,
|
|
62
|
+
});
|
|
63
|
+
if (!session) throw new Error('Unauthorized: No active session.');
|
|
64
|
+
|
|
65
|
+
// Verify that the transaction sender matches the authenticated session address
|
|
66
|
+
if (tx.from && !isSessionMatchingTarget(session, tx.from, tx.chainId)) {
|
|
67
|
+
throw new Error('Forbidden: Session address mismatch.');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Sync the transaction securely to the Quasar Cloud
|
|
62
71
|
await quasar.pulsar.syncCreate(tx, 'My Application');
|
|
63
72
|
return { success: true };
|
|
64
73
|
}
|
|
@@ -66,12 +75,20 @@ export async function syncTransaction(tx: Transaction, sessionData: SiwxSession)
|
|
|
66
75
|
/**
|
|
67
76
|
* Example Next.js Server Action to Fetch History
|
|
68
77
|
*/
|
|
69
|
-
export async function getHistory(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
export async function getHistory(params: {
|
|
79
|
+
walletAddress: string;
|
|
80
|
+
page?: number;
|
|
81
|
+
limit?: number;
|
|
82
|
+
appName?: string;
|
|
83
|
+
chainId?: string;
|
|
84
|
+
}) {
|
|
85
|
+
const session = await getSiwxServerSession({
|
|
86
|
+
cookieSource: await cookies(),
|
|
87
|
+
sessionStore,
|
|
88
|
+
});
|
|
89
|
+
if (!session || !isSessionMatchingTarget(session, params.walletAddress, params.chainId)) {
|
|
90
|
+
throw new Error('Unauthorized: Session address mismatch.');
|
|
91
|
+
}
|
|
75
92
|
|
|
76
93
|
// Return the paginated transaction history
|
|
77
94
|
return quasar.pulsar.getHistory(params);
|
|
@@ -82,11 +99,11 @@ export async function getHistory(
|
|
|
82
99
|
|
|
83
100
|
## 🔐 Frontend Authentication (SIWX)
|
|
84
101
|
|
|
85
|
-
The Quasar SDK relies on the standard **SIWX (CAIP-122)** protocol for authenticating requests.
|
|
102
|
+
The Quasar SDK relies on the standard **SIWX (CAIP-122)** protocol for authenticating client requests.
|
|
86
103
|
|
|
87
|
-
You
|
|
104
|
+
You can use the headless `<NovaSiwxWatcher />` component or `useSiwx` / `useSiwxSession` hooks provided by `@tuwaio/sdk/siwx` (and `@tuwaio/sdk/nova-connect`). The auto-auth watcher automatically prompts users to sign a CAIP-122 message when they connect their wallet and synchronizes active session state.
|
|
88
105
|
|
|
89
|
-
For detailed frontend integration, see the [SIWX Documentation](https://
|
|
106
|
+
For detailed frontend integration, see the [SIWX Documentation](https://siwx.docs.tuwa.io/).
|
|
90
107
|
|
|
91
108
|
---
|
|
92
109
|
|
|
@@ -116,29 +133,49 @@ export type TransactionUnion = SwapTx;
|
|
|
116
133
|
|
|
117
134
|
### 2. Secure Server Proxy (`actions.ts`)
|
|
118
135
|
|
|
119
|
-
Proxy calls to Quasar Cloud using your backend to protect secret keys.
|
|
136
|
+
Proxy calls to Quasar Cloud using your backend to protect secret keys. Never accept client-side session credentials in Server Actions.
|
|
120
137
|
|
|
121
138
|
```ts
|
|
122
139
|
// src/app/actions.ts
|
|
123
140
|
'use server';
|
|
124
141
|
|
|
142
|
+
import { cookies } from 'next/headers';
|
|
125
143
|
import { Quasar } from '@tuwaio/quasar-sdk';
|
|
126
|
-
import {
|
|
144
|
+
import { isSessionMatchingTarget } from '@tuwaio/sdk/siwx';
|
|
145
|
+
import { getSiwxServerSession } from '@tuwaio/sdk/siwx/server';
|
|
146
|
+
import { sessionStore } from '@/lib/authStores';
|
|
127
147
|
import { TransactionUnion } from '@/types';
|
|
128
148
|
|
|
129
149
|
const quasar = new Quasar({ secretKey: process.env.QUASAR_SDK_SK ?? '' });
|
|
130
150
|
|
|
131
|
-
export async function syncTransaction(tx: TransactionUnion
|
|
132
|
-
const
|
|
133
|
-
|
|
151
|
+
export async function syncTransaction(tx: TransactionUnion) {
|
|
152
|
+
const session = await getSiwxServerSession({
|
|
153
|
+
cookieSource: await cookies(),
|
|
154
|
+
sessionStore,
|
|
155
|
+
});
|
|
156
|
+
if (!session) throw new Error('Unauthorized: No active session.');
|
|
157
|
+
if (tx.from && !isSessionMatchingTarget(session, tx.from, tx.chainId)) {
|
|
158
|
+
throw new Error('Forbidden: Session address mismatch.');
|
|
159
|
+
}
|
|
134
160
|
|
|
135
161
|
await quasar.pulsar.syncCreate(tx, 'My App');
|
|
136
162
|
return { success: true };
|
|
137
163
|
}
|
|
138
164
|
|
|
139
|
-
export async function getHistory(params:
|
|
140
|
-
|
|
141
|
-
|
|
165
|
+
export async function getHistory(params: {
|
|
166
|
+
walletAddress: string;
|
|
167
|
+
page?: number;
|
|
168
|
+
limit?: number;
|
|
169
|
+
appName?: string;
|
|
170
|
+
chainId?: string;
|
|
171
|
+
}) {
|
|
172
|
+
const session = await getSiwxServerSession({
|
|
173
|
+
cookieSource: await cookies(),
|
|
174
|
+
sessionStore,
|
|
175
|
+
});
|
|
176
|
+
if (!session || !isSessionMatchingTarget(session, params.walletAddress, params.chainId)) {
|
|
177
|
+
throw new Error('Unauthorized: Session address mismatch.');
|
|
178
|
+
}
|
|
142
179
|
|
|
143
180
|
return quasar.pulsar.getHistory(params);
|
|
144
181
|
}
|
|
@@ -151,7 +188,6 @@ export async function getHistory(params: any, sessionData: SiwxSession) {
|
|
|
151
188
|
import { createPulsarStore, createTxInMemoryStore, createBoundedUseStore } from '@tuwaio/sdk/pulsar';
|
|
152
189
|
import { pulsarEvmAdapter } from '@tuwaio/evm-sdk/pulsar';
|
|
153
190
|
import { pulsarSolanaAdapter } from '@tuwaio/solana-sdk/pulsar';
|
|
154
|
-
import { useSiwxSessionStore } from '@tuwaio/sdk/siwx';
|
|
155
191
|
import { preFlightTxCheck } from '@tuwaio/quasar-sdk';
|
|
156
192
|
|
|
157
193
|
import { getHistory, syncTransaction } from '@/app/actions';
|
|
@@ -170,10 +206,7 @@ const initialStore = createPulsarStore<TransactionUnion>({
|
|
|
170
206
|
onRemoteCreate: async (tx) => {
|
|
171
207
|
try {
|
|
172
208
|
// Syncs the new transaction to Quasar via Next.js Server Actions
|
|
173
|
-
|
|
174
|
-
if (session) {
|
|
175
|
-
await syncTransaction(tx as TransactionUnion, session);
|
|
176
|
-
}
|
|
209
|
+
await syncTransaction(tx as TransactionUnion);
|
|
177
210
|
} catch (err) {
|
|
178
211
|
console.error('[PulsarHook] Remote sync failed:', err);
|
|
179
212
|
}
|
|
@@ -187,10 +220,7 @@ const pulsarInMemoryStore = createTxInMemoryStore<TransactionUnion>({
|
|
|
187
220
|
localTransactionsPool: initialStore.getState().transactionsPool,
|
|
188
221
|
getHistory: async ({ page, walletAddress }) => {
|
|
189
222
|
try {
|
|
190
|
-
const
|
|
191
|
-
if (!session) return null;
|
|
192
|
-
|
|
193
|
-
const history = await getHistory({ walletAddress, page, limit: 10, appName: 'My App' }, session);
|
|
223
|
+
const history = await getHistory({ walletAddress, page, limit: 10, appName: 'My App' });
|
|
194
224
|
|
|
195
225
|
if (!history) return null;
|
|
196
226
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuwaio/quasar-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Oleksandr Tkach",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -82,7 +82,9 @@
|
|
|
82
82
|
"peerDependencies": {
|
|
83
83
|
"@tuwaio/pulsar-core": "^0.6.11",
|
|
84
84
|
"ofetch": "^1.5.1",
|
|
85
|
-
"@tuwaio/siwx-react": "^0.
|
|
85
|
+
"@tuwaio/siwx-react": "^0.2.0",
|
|
86
|
+
"@tuwaio/siwx-core": "^0.2.0",
|
|
87
|
+
"@tuwaio/siwx-server": "^0.2.1"
|
|
86
88
|
},
|
|
87
89
|
"peerDependenciesMeta": {
|
|
88
90
|
"@tuwaio/pulsar-core": {
|
|
@@ -91,23 +93,28 @@
|
|
|
91
93
|
"ofetch": {
|
|
92
94
|
"optional": false
|
|
93
95
|
},
|
|
96
|
+
"@tuwaio/siwx-core": {
|
|
97
|
+
"optional": true
|
|
98
|
+
},
|
|
99
|
+
"@tuwaio/siwx-server": {
|
|
100
|
+
"optional": true
|
|
101
|
+
},
|
|
94
102
|
"@tuwaio/siwx-react": {
|
|
95
103
|
"optional": true
|
|
96
104
|
}
|
|
97
105
|
},
|
|
98
106
|
"devDependencies": {
|
|
99
|
-
"@tuwaio/pulsar-core": "^0.6.
|
|
107
|
+
"@tuwaio/pulsar-core": "^0.6.12",
|
|
100
108
|
"ofetch": "^1.5.1",
|
|
101
109
|
"tsup": "^8.5.1",
|
|
102
110
|
"typescript": "^6.0.3",
|
|
103
|
-
"@tuwaio/siwx-react": "^0.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
"@tuwaio/siwx-core": "^0.1.0",
|
|
107
|
-
"@tuwaio/siwx-server": "^0.1.0"
|
|
111
|
+
"@tuwaio/siwx-react": "^0.2.0",
|
|
112
|
+
"@tuwaio/siwx-core": "^0.2.0",
|
|
113
|
+
"@tuwaio/siwx-server": "^0.2.1"
|
|
108
114
|
},
|
|
109
115
|
"scripts": {
|
|
110
116
|
"start": "tsup src/index.ts --watch",
|
|
111
|
-
"build": "tsup"
|
|
117
|
+
"build": "tsup",
|
|
118
|
+
"test": "node --import tsx --test src/__tests__/*.test.ts"
|
|
112
119
|
}
|
|
113
120
|
}
|