@tuwaio/quasar-sdk 0.1.3 → 0.1.5
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 +64 -33
- package/package.json +10 -9
package/README.md
CHANGED
|
@@ -43,8 +43,11 @@ _Note: `ofetch` and `@tuwaio/pulsar-core` are required peer dependencies. The `@
|
|
|
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 { cookies } from 'next/headers';
|
|
46
47
|
import { Quasar, type Transaction } from '@tuwaio/quasar-sdk';
|
|
47
|
-
import {
|
|
48
|
+
import { isSessionMatchingTarget } from '@tuwaio/sdk/siwx';
|
|
49
|
+
import { getSiwxServerSession } from '@tuwaio/sdk/siwx/server';
|
|
50
|
+
import { sessionStore } from '@/lib/authStores';
|
|
48
51
|
|
|
49
52
|
// Initialize Quasar with your Secret Key from the Dashboard
|
|
50
53
|
const quasar = new Quasar({ secretKey: process.env.QUASAR_SDK_SK ?? '' });
|
|
@@ -52,12 +55,19 @@ const quasar = new Quasar({ secretKey: process.env.QUASAR_SDK_SK ?? '' });
|
|
|
52
55
|
/**
|
|
53
56
|
* Example Next.js Server Action to Sync a Transaction
|
|
54
57
|
*/
|
|
55
|
-
export async function syncTransaction(tx: Transaction
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
|
61
71
|
await quasar.pulsar.syncCreate(tx, 'My Application');
|
|
62
72
|
return { success: true };
|
|
63
73
|
}
|
|
@@ -65,12 +75,20 @@ export async function syncTransaction(tx: Transaction, sessionData: SiwxSession)
|
|
|
65
75
|
/**
|
|
66
76
|
* Example Next.js Server Action to Fetch History
|
|
67
77
|
*/
|
|
68
|
-
export async function getHistory(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
+
}
|
|
74
92
|
|
|
75
93
|
// Return the paginated transaction history
|
|
76
94
|
return quasar.pulsar.getHistory(params);
|
|
@@ -81,11 +99,11 @@ export async function getHistory(
|
|
|
81
99
|
|
|
82
100
|
## 🔐 Frontend Authentication (SIWX)
|
|
83
101
|
|
|
84
|
-
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.
|
|
85
103
|
|
|
86
|
-
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.
|
|
87
105
|
|
|
88
|
-
For detailed frontend integration, see the [SIWX Documentation](https://
|
|
106
|
+
For detailed frontend integration, see the [SIWX Documentation](https://siwx.docs.tuwa.io/).
|
|
89
107
|
|
|
90
108
|
---
|
|
91
109
|
|
|
@@ -115,29 +133,49 @@ export type TransactionUnion = SwapTx;
|
|
|
115
133
|
|
|
116
134
|
### 2. Secure Server Proxy (`actions.ts`)
|
|
117
135
|
|
|
118
|
-
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.
|
|
119
137
|
|
|
120
138
|
```ts
|
|
121
139
|
// src/app/actions.ts
|
|
122
140
|
'use server';
|
|
123
141
|
|
|
142
|
+
import { cookies } from 'next/headers';
|
|
124
143
|
import { Quasar } from '@tuwaio/quasar-sdk';
|
|
125
|
-
import {
|
|
144
|
+
import { isSessionMatchingTarget } from '@tuwaio/sdk/siwx';
|
|
145
|
+
import { getSiwxServerSession } from '@tuwaio/sdk/siwx/server';
|
|
146
|
+
import { sessionStore } from '@/lib/authStores';
|
|
126
147
|
import { TransactionUnion } from '@/types';
|
|
127
148
|
|
|
128
149
|
const quasar = new Quasar({ secretKey: process.env.QUASAR_SDK_SK ?? '' });
|
|
129
150
|
|
|
130
|
-
export async function syncTransaction(tx: TransactionUnion
|
|
131
|
-
const
|
|
132
|
-
|
|
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
|
+
}
|
|
133
160
|
|
|
134
161
|
await quasar.pulsar.syncCreate(tx, 'My App');
|
|
135
162
|
return { success: true };
|
|
136
163
|
}
|
|
137
164
|
|
|
138
|
-
export async function getHistory(params:
|
|
139
|
-
|
|
140
|
-
|
|
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
|
+
}
|
|
141
179
|
|
|
142
180
|
return quasar.pulsar.getHistory(params);
|
|
143
181
|
}
|
|
@@ -150,7 +188,6 @@ export async function getHistory(params: any, sessionData: SiwxSession) {
|
|
|
150
188
|
import { createPulsarStore, createTxInMemoryStore, createBoundedUseStore } from '@tuwaio/sdk/pulsar';
|
|
151
189
|
import { pulsarEvmAdapter } from '@tuwaio/evm-sdk/pulsar';
|
|
152
190
|
import { pulsarSolanaAdapter } from '@tuwaio/solana-sdk/pulsar';
|
|
153
|
-
import { useSiwxSessionStore } from '@tuwaio/sdk/siwx';
|
|
154
191
|
import { preFlightTxCheck } from '@tuwaio/quasar-sdk';
|
|
155
192
|
|
|
156
193
|
import { getHistory, syncTransaction } from '@/app/actions';
|
|
@@ -169,10 +206,7 @@ const initialStore = createPulsarStore<TransactionUnion>({
|
|
|
169
206
|
onRemoteCreate: async (tx) => {
|
|
170
207
|
try {
|
|
171
208
|
// Syncs the new transaction to Quasar via Next.js Server Actions
|
|
172
|
-
|
|
173
|
-
if (session) {
|
|
174
|
-
await syncTransaction(tx as TransactionUnion, session);
|
|
175
|
-
}
|
|
209
|
+
await syncTransaction(tx as TransactionUnion);
|
|
176
210
|
} catch (err) {
|
|
177
211
|
console.error('[PulsarHook] Remote sync failed:', err);
|
|
178
212
|
}
|
|
@@ -186,10 +220,7 @@ const pulsarInMemoryStore = createTxInMemoryStore<TransactionUnion>({
|
|
|
186
220
|
localTransactionsPool: initialStore.getState().transactionsPool,
|
|
187
221
|
getHistory: async ({ page, walletAddress }) => {
|
|
188
222
|
try {
|
|
189
|
-
const
|
|
190
|
-
if (!session) return null;
|
|
191
|
-
|
|
192
|
-
const history = await getHistory({ walletAddress, page, limit: 10, appName: 'My App' }, session);
|
|
223
|
+
const history = await getHistory({ walletAddress, page, limit: 10, appName: 'My App' });
|
|
193
224
|
|
|
194
225
|
if (!history) return null;
|
|
195
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.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Oleksandr Tkach",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -82,9 +82,9 @@
|
|
|
82
82
|
"peerDependencies": {
|
|
83
83
|
"@tuwaio/pulsar-core": "^0.6.11",
|
|
84
84
|
"ofetch": "^1.5.1",
|
|
85
|
-
"@tuwaio/siwx-react": "^0.
|
|
86
|
-
"@tuwaio/siwx-core": "^0.
|
|
87
|
-
"@tuwaio/siwx-server": "^0.1
|
|
85
|
+
"@tuwaio/siwx-react": "^0.2.0",
|
|
86
|
+
"@tuwaio/siwx-core": "^0.2.0",
|
|
87
|
+
"@tuwaio/siwx-server": "^0.2.1"
|
|
88
88
|
},
|
|
89
89
|
"peerDependenciesMeta": {
|
|
90
90
|
"@tuwaio/pulsar-core": {
|
|
@@ -107,13 +107,14 @@
|
|
|
107
107
|
"@tuwaio/pulsar-core": "^0.6.12",
|
|
108
108
|
"ofetch": "^1.5.1",
|
|
109
109
|
"tsup": "^8.5.1",
|
|
110
|
-
"typescript": "
|
|
111
|
-
"@tuwaio/siwx-react": "^0.
|
|
112
|
-
"@tuwaio/siwx-core": "^0.1
|
|
113
|
-
"@tuwaio/siwx-server": "^0.
|
|
110
|
+
"typescript": "6.0.3",
|
|
111
|
+
"@tuwaio/siwx-react": "^0.2.1",
|
|
112
|
+
"@tuwaio/siwx-core": "^0.2.1",
|
|
113
|
+
"@tuwaio/siwx-server": "^0.2.2"
|
|
114
114
|
},
|
|
115
115
|
"scripts": {
|
|
116
116
|
"start": "tsup src/index.ts --watch",
|
|
117
|
-
"build": "tsup"
|
|
117
|
+
"build": "tsup",
|
|
118
|
+
"test": "node --import tsx --test src/__tests__/*.test.ts"
|
|
118
119
|
}
|
|
119
120
|
}
|