@pooflabs/web 0.0.73 → 0.0.74
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/dist/auth/index.d.ts +4 -5
- package/dist/auth/providers/mock-auth-provider.d.ts +3 -3
- package/dist/auth/providers/privy-expo-provider.d.ts +105 -0
- package/dist/{index-BFJJZKXQ.js → index-BVfqY0fJ.js} +2761 -7
- package/dist/index-BVfqY0fJ.js.map +1 -0
- package/dist/index-Bdcc5821.js +2375 -0
- package/dist/index-Bdcc5821.js.map +1 -0
- package/dist/{index-TfCOBCez.esm.js → index-ByH7PSr3.esm.js} +2756 -2
- package/dist/index-ByH7PSr3.esm.js.map +1 -0
- package/dist/index-CVK4iKo4.js +21508 -0
- package/dist/index-CVK4iKo4.js.map +1 -0
- package/dist/index-CrOVJFX9.esm.js +2373 -0
- package/dist/index-CrOVJFX9.esm.js.map +1 -0
- package/dist/index-ORXorrQK.esm.js +18291 -0
- package/dist/index-ORXorrQK.esm.js.map +1 -0
- package/dist/index-QqlKSXH4.js +18332 -0
- package/dist/index-QqlKSXH4.js.map +1 -0
- package/dist/index-tYJgJQDc.esm.js +21430 -0
- package/dist/index-tYJgJQDc.esm.js.map +1 -0
- package/dist/index.browser-B8vmX-tI.js +1471 -0
- package/dist/index.browser-B8vmX-tI.js.map +1 -0
- package/dist/{index.browser-ChrwVq76.esm.js → index.browser-C2K1wE09.esm.js} +2 -3
- package/dist/{index.browser-ChrwVq76.esm.js.map → index.browser-C2K1wE09.esm.js.map} +1 -1
- package/dist/index.browser-D63nJFKg.esm.js +1468 -0
- package/dist/index.browser-D63nJFKg.esm.js.map +1 -0
- package/dist/{index.browser-BuIgwfvv.esm.js → index.browser-DTId19-8.esm.js} +2 -3
- package/dist/{index.browser-BuIgwfvv.esm.js.map → index.browser-DTId19-8.esm.js.map} +1 -1
- package/dist/{index.browser-wsb8xknL.js → index.browser-De6JT7NR.js} +2 -3
- package/dist/{index.browser-wsb8xknL.js.map → index.browser-De6JT7NR.js.map} +1 -1
- package/dist/{index.browser-BO1XxDi0.js → index.browser-GM5fUBfQ.js} +2 -3
- package/dist/{index.browser-BO1XxDi0.js.map → index.browser-GM5fUBfQ.js.map} +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.esm.js +1 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/index.native-CzfZTw_J.esm.js +13211 -0
- package/dist/index.native-CzfZTw_J.esm.js.map +1 -0
- package/dist/index.native-muw49g7i.js +13290 -0
- package/dist/index.native-muw49g7i.js.map +1 -0
- package/dist/index.native.d.ts +24 -0
- package/dist/index.native.esm.js +6 -0
- package/dist/index.native.esm.js.map +1 -0
- package/dist/index.native.js +59 -0
- package/dist/index.native.js.map +1 -0
- package/dist/phantom-wallet-provider-CeNZvRZY.js +1328 -0
- package/dist/phantom-wallet-provider-CeNZvRZY.js.map +1 -0
- package/dist/phantom-wallet-provider-Di3Z8vOA.esm.js +1307 -0
- package/dist/phantom-wallet-provider-Di3Z8vOA.esm.js.map +1 -0
- package/dist/platform.d.ts +68 -0
- package/dist/privy-wallet-provider-Cfws3b3x.esm.js +3921 -0
- package/dist/privy-wallet-provider-Cfws3b3x.esm.js.map +1 -0
- package/dist/privy-wallet-provider-lbg2fDVg.js +3942 -0
- package/dist/privy-wallet-provider-lbg2fDVg.js.map +1 -0
- package/dist/solana-mobile-wallet-provider-BZMvp9Qy.esm.js +558 -0
- package/dist/solana-mobile-wallet-provider-BZMvp9Qy.esm.js.map +1 -0
- package/dist/solana-mobile-wallet-provider-DDqwl25J.js +579 -0
- package/dist/solana-mobile-wallet-provider-DDqwl25J.js.map +1 -0
- package/package.json +19 -3
- package/dist/index-BFJJZKXQ.js.map +0 -1
- package/dist/index-BV8MOXXy.js +0 -36033
- package/dist/index-BV8MOXXy.js.map +0 -1
- package/dist/index-D0yz-P8G.esm.js +0 -35962
- package/dist/index-D0yz-P8G.esm.js.map +0 -1
- package/dist/index-TfCOBCez.esm.js.map +0 -1
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
import { b as bufferExports } from './index-CrOVJFX9.esm.js';
|
|
2
|
+
import { g as getPlatform, i as setAuthLoading, W as WebSessionManager, s as setCurrentUser, j as genAuthNonce, k as genSolanaMessage, l as createSessionWithSignature, e as confirmAndCheckTransaction, c as convertRemainingAccounts, b as buildSetDocumentsTransaction, a as SOLANA_DEVNET_RPC_URL, S as SOLANA_MAINNET_RPC_URL, h as SURFNET_RPC_URL } from './index.native-CzfZTw_J.esm.js';
|
|
3
|
+
import { PublicKey, Connection, VersionedTransaction } from '@solana/web3.js';
|
|
4
|
+
import * as anchor from '@coral-xyz/anchor';
|
|
5
|
+
import 'axios';
|
|
6
|
+
import 'react';
|
|
7
|
+
|
|
8
|
+
const ED25519_SIGNATURE_LENGTH = 64;
|
|
9
|
+
// Dynamically imported MWA protocol module
|
|
10
|
+
let mwaProtocolModule = null;
|
|
11
|
+
let mwaProtocolLoadPromise = null;
|
|
12
|
+
async function loadMwaProtocol() {
|
|
13
|
+
if (mwaProtocolModule)
|
|
14
|
+
return;
|
|
15
|
+
if (typeof window === 'undefined')
|
|
16
|
+
return;
|
|
17
|
+
if (mwaProtocolLoadPromise)
|
|
18
|
+
return mwaProtocolLoadPromise;
|
|
19
|
+
mwaProtocolLoadPromise = (async () => {
|
|
20
|
+
try {
|
|
21
|
+
mwaProtocolModule = await import('./index.browser-D63nJFKg.esm.js');
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
console.warn('[SolanaMobileWallet] @solana-mobile/mobile-wallet-adapter-protocol-web3js not installed. Install it to enable Seeker wallet support.');
|
|
25
|
+
throw new Error('Missing @solana-mobile/mobile-wallet-adapter-protocol-web3js dependency');
|
|
26
|
+
}
|
|
27
|
+
})();
|
|
28
|
+
return mwaProtocolLoadPromise;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* SolanaMobileWalletProvider implements the AuthProvider interface using the
|
|
32
|
+
* Solana Mobile Wallet Adapter (MWA) protocol's low-level `transact` API.
|
|
33
|
+
*
|
|
34
|
+
* This enables TaroBase dApps to work with any MWA-compliant wallet on Solana
|
|
35
|
+
* mobile devices (Seeker, Saga) — including the native Seed Vault Wallet,
|
|
36
|
+
* Phantom, Solflare, and any other wallet that implements the MWA protocol.
|
|
37
|
+
*
|
|
38
|
+
* By using `transact()` directly (instead of the wallet-adapter wrapper),
|
|
39
|
+
* login combines authorize + signMessage into a single wallet session —
|
|
40
|
+
* meaning one popup/approval instead of two.
|
|
41
|
+
*/
|
|
42
|
+
class SolanaMobileWalletProvider {
|
|
43
|
+
constructor(networkUrl = null, config = {}) {
|
|
44
|
+
// MWA authorization state
|
|
45
|
+
this.authToken = null;
|
|
46
|
+
this.walletUriBase = null;
|
|
47
|
+
this.base64Address = null;
|
|
48
|
+
this.authorizedPublicKey = null;
|
|
49
|
+
this.publicKeyObj = null;
|
|
50
|
+
this.networkUrl = networkUrl;
|
|
51
|
+
this.config = config;
|
|
52
|
+
if (typeof window === 'undefined') {
|
|
53
|
+
throw new Error('SolanaMobileWalletProvider can only be instantiated in a browser environment');
|
|
54
|
+
}
|
|
55
|
+
if (SolanaMobileWalletProvider.instance) {
|
|
56
|
+
return SolanaMobileWalletProvider.instance;
|
|
57
|
+
}
|
|
58
|
+
this.appIdentity = config.appIdentity || {
|
|
59
|
+
name: 'TaroBase App',
|
|
60
|
+
uri: getPlatform().getLocationOrigin(),
|
|
61
|
+
};
|
|
62
|
+
this.chain = `solana:${config.cluster || 'mainnet-beta'}`;
|
|
63
|
+
SolanaMobileWalletProvider.instance = this;
|
|
64
|
+
}
|
|
65
|
+
static getInstance(networkUrl, config) {
|
|
66
|
+
if (!SolanaMobileWalletProvider.instance) {
|
|
67
|
+
new SolanaMobileWalletProvider(networkUrl, config);
|
|
68
|
+
}
|
|
69
|
+
return SolanaMobileWalletProvider.instance;
|
|
70
|
+
}
|
|
71
|
+
/** Config for transact() — routes to the same wallet if we've already authorized */
|
|
72
|
+
getAssociationConfig() {
|
|
73
|
+
if (this.walletUriBase) {
|
|
74
|
+
return { baseUri: this.walletUriBase };
|
|
75
|
+
}
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
/** Reauthorize within a transact callback using a stored auth_token */
|
|
79
|
+
async reauthorizeWallet(wallet) {
|
|
80
|
+
if (!this.authToken) {
|
|
81
|
+
// No existing auth — do a fresh authorize
|
|
82
|
+
const authResult = await wallet.authorize({
|
|
83
|
+
identity: this.appIdentity,
|
|
84
|
+
chain: this.chain,
|
|
85
|
+
});
|
|
86
|
+
this.storeAuthResult(authResult);
|
|
87
|
+
return authResult;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
const authResult = await wallet.reauthorize({
|
|
91
|
+
auth_token: this.authToken,
|
|
92
|
+
identity: this.appIdentity,
|
|
93
|
+
});
|
|
94
|
+
this.storeAuthResult(authResult);
|
|
95
|
+
return authResult;
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
// Reauth failed (token expired, wallet reset, etc.) — try fresh authorize
|
|
99
|
+
console.warn('[SolanaMobileWallet] Reauthorization failed, attempting fresh authorize:', e === null || e === void 0 ? void 0 : e.message);
|
|
100
|
+
const authResult = await wallet.authorize({
|
|
101
|
+
identity: this.appIdentity,
|
|
102
|
+
chain: this.chain,
|
|
103
|
+
});
|
|
104
|
+
this.storeAuthResult(authResult);
|
|
105
|
+
return authResult;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** Persist auth result from an authorize/reauthorize call */
|
|
109
|
+
storeAuthResult(authResult) {
|
|
110
|
+
var _a;
|
|
111
|
+
this.authToken = authResult.auth_token;
|
|
112
|
+
this.walletUriBase = authResult.wallet_uri_base;
|
|
113
|
+
if (((_a = authResult.accounts) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
114
|
+
const account = authResult.accounts[0];
|
|
115
|
+
this.base64Address = account.address;
|
|
116
|
+
// Decode base64 address → PublicKey → base58
|
|
117
|
+
const addressBytes = Uint8Array.from(getPlatform().atob(account.address), c => c.charCodeAt(0));
|
|
118
|
+
this.publicKeyObj = new PublicKey(addressBytes);
|
|
119
|
+
this.authorizedPublicKey = this.publicKeyObj.toBase58();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async login() {
|
|
123
|
+
var _a, _b, _c, _d, _e;
|
|
124
|
+
setAuthLoading(true);
|
|
125
|
+
try {
|
|
126
|
+
await loadMwaProtocol();
|
|
127
|
+
const { transact } = mwaProtocolModule;
|
|
128
|
+
// Quick check: if we already have auth state and a valid session, skip
|
|
129
|
+
if (this.authorizedPublicKey) {
|
|
130
|
+
const existingSession = await WebSessionManager.getSession();
|
|
131
|
+
if (existingSession && existingSession.address === this.authorizedPublicKey) {
|
|
132
|
+
const user = { provider: this, address: this.authorizedPublicKey };
|
|
133
|
+
setCurrentUser(user);
|
|
134
|
+
return user;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Pre-fetch nonce from server while wallet is not yet connected
|
|
138
|
+
const nonce = await genAuthNonce();
|
|
139
|
+
// Single transact() call: authorize + signMessages — one wallet popup
|
|
140
|
+
const result = await transact(async (wallet) => {
|
|
141
|
+
// Step 1: Authorize — user approves the dApp
|
|
142
|
+
const authResult = await wallet.authorize({
|
|
143
|
+
identity: this.appIdentity,
|
|
144
|
+
chain: this.chain,
|
|
145
|
+
});
|
|
146
|
+
const base64Addr = authResult.accounts[0].address;
|
|
147
|
+
const addressBytes = Uint8Array.from(getPlatform().atob(base64Addr), c => c.charCodeAt(0));
|
|
148
|
+
const pubkey = new PublicKey(addressBytes);
|
|
149
|
+
const base58Addr = pubkey.toBase58();
|
|
150
|
+
// Step 2: Sign the auth message — still in the same wallet session
|
|
151
|
+
const messageText = await genSolanaMessage(base58Addr, nonce);
|
|
152
|
+
const messageBytes = getPlatform().textEncode(messageText);
|
|
153
|
+
const signedMessages = await wallet.signMessages({
|
|
154
|
+
addresses: [base64Addr],
|
|
155
|
+
payloads: [messageBytes],
|
|
156
|
+
});
|
|
157
|
+
// The signed payload is [original message bytes][64-byte ed25519 signature]
|
|
158
|
+
const signedPayload = signedMessages[0];
|
|
159
|
+
const signatureBytes = signedPayload.slice(-ED25519_SIGNATURE_LENGTH);
|
|
160
|
+
return {
|
|
161
|
+
base58Address: base58Addr,
|
|
162
|
+
base64Address: base64Addr,
|
|
163
|
+
publicKey: pubkey,
|
|
164
|
+
signature: bufferExports.Buffer.from(signatureBytes).toString('base64'),
|
|
165
|
+
messageText,
|
|
166
|
+
authToken: authResult.auth_token,
|
|
167
|
+
walletUriBase: authResult.wallet_uri_base,
|
|
168
|
+
};
|
|
169
|
+
}, this.getAssociationConfig());
|
|
170
|
+
// Store MWA auth state for reauthorization in subsequent transact() calls
|
|
171
|
+
this.authToken = result.authToken;
|
|
172
|
+
this.walletUriBase = result.walletUriBase;
|
|
173
|
+
this.base64Address = result.base64Address;
|
|
174
|
+
this.authorizedPublicKey = result.base58Address;
|
|
175
|
+
this.publicKeyObj = result.publicKey;
|
|
176
|
+
// Check if we already have a valid session for this address
|
|
177
|
+
const existingSession = await WebSessionManager.getSession();
|
|
178
|
+
if (existingSession && existingSession.address === result.base58Address) {
|
|
179
|
+
const user = { provider: this, address: result.base58Address };
|
|
180
|
+
setCurrentUser(user);
|
|
181
|
+
return user;
|
|
182
|
+
}
|
|
183
|
+
// Create new session on the server
|
|
184
|
+
const createSessionResult = await createSessionWithSignature(result.base58Address, result.messageText, result.signature);
|
|
185
|
+
await WebSessionManager.storeSession(result.base58Address, createSessionResult.accessToken, createSessionResult.idToken, createSessionResult.refreshToken);
|
|
186
|
+
// Mark auth method
|
|
187
|
+
try {
|
|
188
|
+
getPlatform().storage.setItem('tarobase_last_auth_method', 'mobile-wallet-adapter');
|
|
189
|
+
}
|
|
190
|
+
catch (_f) { }
|
|
191
|
+
const user = { provider: this, address: result.base58Address };
|
|
192
|
+
setCurrentUser(user);
|
|
193
|
+
return user;
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
const isUserRejection = (error === null || error === void 0 ? void 0 : error.code) === 4001 ||
|
|
197
|
+
((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes('user rejected')) ||
|
|
198
|
+
((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.toLowerCase().includes('user denied')) ||
|
|
199
|
+
((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.toLowerCase().includes('user cancelled')) ||
|
|
200
|
+
((_d = error === null || error === void 0 ? void 0 : error.message) === null || _d === void 0 ? void 0 : _d.toLowerCase().includes('user canceled')) ||
|
|
201
|
+
((_e = error === null || error === void 0 ? void 0 : error.message) === null || _e === void 0 ? void 0 : _e.toLowerCase().includes('user declined'));
|
|
202
|
+
if (!isUserRejection) {
|
|
203
|
+
console.error('[SolanaMobileWallet] Login failed:', error);
|
|
204
|
+
}
|
|
205
|
+
throw error;
|
|
206
|
+
}
|
|
207
|
+
finally {
|
|
208
|
+
setAuthLoading(false);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async restoreSession() {
|
|
212
|
+
const session = await WebSessionManager.getSession();
|
|
213
|
+
if (session) {
|
|
214
|
+
this.authorizedPublicKey = session.address;
|
|
215
|
+
this.publicKeyObj = new PublicKey(session.address);
|
|
216
|
+
return { provider: this, address: session.address };
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
async logout() {
|
|
221
|
+
// Deauthorize with the wallet if we have an auth_token
|
|
222
|
+
if (this.authToken) {
|
|
223
|
+
try {
|
|
224
|
+
await loadMwaProtocol();
|
|
225
|
+
const { transact } = mwaProtocolModule;
|
|
226
|
+
const authToken = this.authToken;
|
|
227
|
+
await transact(async (wallet) => {
|
|
228
|
+
await wallet.deauthorize({ auth_token: authToken });
|
|
229
|
+
}, this.getAssociationConfig());
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
console.error('[SolanaMobileWallet] Deauthorize error:', error);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
this.authToken = null;
|
|
236
|
+
this.walletUriBase = null;
|
|
237
|
+
this.base64Address = null;
|
|
238
|
+
this.authorizedPublicKey = null;
|
|
239
|
+
this.publicKeyObj = null;
|
|
240
|
+
WebSessionManager.clearSession();
|
|
241
|
+
setCurrentUser(null);
|
|
242
|
+
}
|
|
243
|
+
async signMessage(message) {
|
|
244
|
+
var _a, _b;
|
|
245
|
+
if (!this.authorizedPublicKey || !this.base64Address) {
|
|
246
|
+
throw new Error('Not connected. Call login() first.');
|
|
247
|
+
}
|
|
248
|
+
await loadMwaProtocol();
|
|
249
|
+
const { transact } = mwaProtocolModule;
|
|
250
|
+
const base64Addr = this.base64Address;
|
|
251
|
+
try {
|
|
252
|
+
const signedMessages = await transact(async (wallet) => {
|
|
253
|
+
await this.reauthorizeWallet(wallet);
|
|
254
|
+
const messageBytes = getPlatform().textEncode(message);
|
|
255
|
+
return wallet.signMessages({
|
|
256
|
+
addresses: [base64Addr],
|
|
257
|
+
payloads: [messageBytes],
|
|
258
|
+
});
|
|
259
|
+
}, this.getAssociationConfig());
|
|
260
|
+
const signedPayload = signedMessages[0];
|
|
261
|
+
const signatureBytes = signedPayload.slice(-ED25519_SIGNATURE_LENGTH);
|
|
262
|
+
return bufferExports.Buffer.from(signatureBytes).toString('base64');
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('not connected')) || ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('not authorized')) ||
|
|
266
|
+
(error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED') {
|
|
267
|
+
await this.logout();
|
|
268
|
+
throw new Error('Wallet connection lost. Please reconnect.');
|
|
269
|
+
}
|
|
270
|
+
throw new Error(`Failed to sign message: ${error.message}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
async signTransaction(transaction) {
|
|
274
|
+
var _a, _b;
|
|
275
|
+
if (!this.publicKeyObj) {
|
|
276
|
+
throw new Error('Not connected. Call login() first.');
|
|
277
|
+
}
|
|
278
|
+
await loadMwaProtocol();
|
|
279
|
+
const { transact } = mwaProtocolModule;
|
|
280
|
+
// Ensure blockhash and fee payer are set before signing
|
|
281
|
+
const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
|
|
282
|
+
if (isLegacyTransaction) {
|
|
283
|
+
const legacyTx = transaction;
|
|
284
|
+
if (!legacyTx.recentBlockhash) {
|
|
285
|
+
const rpcUrl = this.getRpcUrl();
|
|
286
|
+
const connection = new Connection(rpcUrl, 'confirmed');
|
|
287
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
|
|
288
|
+
legacyTx.recentBlockhash = blockhash;
|
|
289
|
+
legacyTx.lastValidBlockHeight = lastValidBlockHeight;
|
|
290
|
+
}
|
|
291
|
+
if (!legacyTx.feePayer && this.publicKeyObj) {
|
|
292
|
+
legacyTx.feePayer = this.publicKeyObj;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
const versionedTx = transaction;
|
|
297
|
+
if (!versionedTx.message.recentBlockhash) {
|
|
298
|
+
const rpcUrl = this.getRpcUrl();
|
|
299
|
+
const connection = new Connection(rpcUrl, 'confirmed');
|
|
300
|
+
const { blockhash } = await connection.getLatestBlockhash('confirmed');
|
|
301
|
+
versionedTx.message.recentBlockhash = blockhash;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
try {
|
|
305
|
+
const signedTransactions = await transact(async (wallet) => {
|
|
306
|
+
await this.reauthorizeWallet(wallet);
|
|
307
|
+
return wallet.signTransactions({ transactions: [transaction] });
|
|
308
|
+
}, this.getAssociationConfig());
|
|
309
|
+
return signedTransactions[0];
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('not connected')) || ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('not authorized')) ||
|
|
313
|
+
(error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED') {
|
|
314
|
+
await this.logout();
|
|
315
|
+
throw new Error('Wallet connection lost. Please reconnect.');
|
|
316
|
+
}
|
|
317
|
+
throw new Error(`Failed to sign transaction: ${error.message}`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
async signAndSubmitTransaction(transaction, feePayer) {
|
|
321
|
+
var _a, _b, _c, _d, _e, _f;
|
|
322
|
+
if (!this.publicKeyObj) {
|
|
323
|
+
throw new Error('Not connected. Call login() first.');
|
|
324
|
+
}
|
|
325
|
+
await loadMwaProtocol();
|
|
326
|
+
const { transact } = mwaProtocolModule;
|
|
327
|
+
const rpcUrl = this.getRpcUrl();
|
|
328
|
+
const connection = new Connection(rpcUrl, 'confirmed');
|
|
329
|
+
const isSurfnet = rpcUrl === SURFNET_RPC_URL;
|
|
330
|
+
try {
|
|
331
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
|
|
332
|
+
const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
|
|
333
|
+
if (isLegacyTransaction) {
|
|
334
|
+
const legacyTx = transaction;
|
|
335
|
+
legacyTx.recentBlockhash = blockhash;
|
|
336
|
+
legacyTx.lastValidBlockHeight = lastValidBlockHeight;
|
|
337
|
+
if (!legacyTx.feePayer) {
|
|
338
|
+
if (feePayer) {
|
|
339
|
+
legacyTx.feePayer = feePayer;
|
|
340
|
+
}
|
|
341
|
+
else if (this.publicKeyObj) {
|
|
342
|
+
legacyTx.feePayer = this.publicKeyObj;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
const versionedTx = transaction;
|
|
348
|
+
versionedTx.message.recentBlockhash = blockhash;
|
|
349
|
+
}
|
|
350
|
+
if (isSurfnet) {
|
|
351
|
+
// Surfnet: sign-only, then submit to our specific RPC
|
|
352
|
+
const signedTransactions = await transact(async (wallet) => {
|
|
353
|
+
await this.reauthorizeWallet(wallet);
|
|
354
|
+
return wallet.signTransactions({ transactions: [transaction] });
|
|
355
|
+
}, this.getAssociationConfig());
|
|
356
|
+
const signedTx = signedTransactions[0];
|
|
357
|
+
const signature = await connection.sendRawTransaction(signedTx.serialize(), {
|
|
358
|
+
preflightCommitment: 'confirmed'
|
|
359
|
+
});
|
|
360
|
+
const confirmation = await connection.confirmTransaction({
|
|
361
|
+
signature,
|
|
362
|
+
blockhash,
|
|
363
|
+
lastValidBlockHeight,
|
|
364
|
+
}, 'confirmed');
|
|
365
|
+
if (confirmation.value.err) {
|
|
366
|
+
throw new Error(`Transaction failed: ${confirmation.value.err.toString()}`);
|
|
367
|
+
}
|
|
368
|
+
return signature;
|
|
369
|
+
}
|
|
370
|
+
// Non-surfnet: use signAndSendTransactions for wallet-optimized submission
|
|
371
|
+
const signatures = await transact(async (wallet) => {
|
|
372
|
+
await this.reauthorizeWallet(wallet);
|
|
373
|
+
return wallet.signAndSendTransactions({
|
|
374
|
+
transactions: [transaction],
|
|
375
|
+
commitment: 'confirmed',
|
|
376
|
+
});
|
|
377
|
+
}, this.getAssociationConfig());
|
|
378
|
+
const signature = signatures[0];
|
|
379
|
+
await confirmAndCheckTransaction(connection, signature);
|
|
380
|
+
return signature;
|
|
381
|
+
}
|
|
382
|
+
catch (error) {
|
|
383
|
+
if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('not connected')) || ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('not authorized')) ||
|
|
384
|
+
(error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED') {
|
|
385
|
+
await this.logout();
|
|
386
|
+
throw new Error('Wallet connection lost. Please reconnect.');
|
|
387
|
+
}
|
|
388
|
+
const isUserRejection = (error === null || error === void 0 ? void 0 : error.code) === 4001 ||
|
|
389
|
+
((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.toLowerCase().includes('user rejected')) ||
|
|
390
|
+
((_d = error === null || error === void 0 ? void 0 : error.message) === null || _d === void 0 ? void 0 : _d.toLowerCase().includes('user denied')) ||
|
|
391
|
+
((_e = error === null || error === void 0 ? void 0 : error.message) === null || _e === void 0 ? void 0 : _e.toLowerCase().includes('user cancelled')) ||
|
|
392
|
+
((_f = error === null || error === void 0 ? void 0 : error.message) === null || _f === void 0 ? void 0 : _f.toLowerCase().includes('user canceled'));
|
|
393
|
+
if (!isUserRejection) {
|
|
394
|
+
console.error('[SolanaMobileWallet] Transaction failed:', error);
|
|
395
|
+
}
|
|
396
|
+
throw new Error(`Failed to execute transaction: ${error.message}`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
async runTransaction(_evmTransactionData, solTransactionData, options) {
|
|
400
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
401
|
+
if (!solTransactionData) {
|
|
402
|
+
throw new Error('Solana transaction data is required for mobile wallet');
|
|
403
|
+
}
|
|
404
|
+
if (!this.publicKeyObj || !this.authorizedPublicKey) {
|
|
405
|
+
await this.login();
|
|
406
|
+
}
|
|
407
|
+
await loadMwaProtocol();
|
|
408
|
+
const { transact } = mwaProtocolModule;
|
|
409
|
+
const rpcUrl = this.getRpcUrl(solTransactionData.network);
|
|
410
|
+
const connection = new Connection(rpcUrl, 'confirmed');
|
|
411
|
+
const isSurfnet = rpcUrl === SURFNET_RPC_URL;
|
|
412
|
+
try {
|
|
413
|
+
const publicKey = this.publicKeyObj;
|
|
414
|
+
const remainingAccounts = convertRemainingAccounts(solTransactionData.txArgs[0].remainingAccounts);
|
|
415
|
+
let app_id = solTransactionData.appId;
|
|
416
|
+
if (typeof window !== 'undefined' && window.CUSTOM_TAROBASE_APP_ID_HEADER) {
|
|
417
|
+
app_id = window.CUSTOM_TAROBASE_APP_ID_HEADER;
|
|
418
|
+
}
|
|
419
|
+
if (!app_id) {
|
|
420
|
+
throw new Error('App ID is required');
|
|
421
|
+
}
|
|
422
|
+
// Create a mock wallet adapter for Anchor (only publicKey is needed for building TX)
|
|
423
|
+
const mockWalletAdapter = {
|
|
424
|
+
publicKey,
|
|
425
|
+
signTransaction: async (tx) => tx,
|
|
426
|
+
signAllTransactions: async (txs) => txs,
|
|
427
|
+
};
|
|
428
|
+
const anchorProvider = new anchor.AnchorProvider(connection, mockWalletAdapter, anchor.AnchorProvider.defaultOptions());
|
|
429
|
+
const finalDeduped = [];
|
|
430
|
+
for (const acc of remainingAccounts) {
|
|
431
|
+
const existing = finalDeduped.find((d) => d.pubkey.equals(acc.pubkey));
|
|
432
|
+
if (existing) {
|
|
433
|
+
existing.isSigner = existing.isSigner || acc.isSigner;
|
|
434
|
+
existing.isWritable = existing.isWritable || acc.isWritable;
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
finalDeduped.push(acc);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
let tx;
|
|
441
|
+
if (solTransactionData.signedTransaction) {
|
|
442
|
+
tx = VersionedTransaction.deserialize(bufferExports.Buffer.from(solTransactionData.signedTransaction, 'base64'));
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
const result = await buildSetDocumentsTransaction(connection, solTransactionData.txArgs[0].idl, anchorProvider, publicKey, {
|
|
446
|
+
app_id,
|
|
447
|
+
documents: solTransactionData.txArgs[0].setDocumentData,
|
|
448
|
+
delete_paths: solTransactionData.txArgs[0].deletePaths,
|
|
449
|
+
txData: solTransactionData.txArgs[0].txData
|
|
450
|
+
}, finalDeduped, solTransactionData.lutKey, solTransactionData.preInstructions, false);
|
|
451
|
+
tx = result.tx;
|
|
452
|
+
}
|
|
453
|
+
if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false) {
|
|
454
|
+
const [signedTx] = await transact(async (wallet) => {
|
|
455
|
+
await this.reauthorizeWallet(wallet);
|
|
456
|
+
return wallet.signTransactions({ transactions: [tx] });
|
|
457
|
+
}, this.getAssociationConfig());
|
|
458
|
+
return {
|
|
459
|
+
signedTransaction: signedTx,
|
|
460
|
+
blockNumber: 0,
|
|
461
|
+
gasUsed: '0',
|
|
462
|
+
data: ''
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
if (isSurfnet) {
|
|
466
|
+
// Surfnet: sign then submit manually to our RPC
|
|
467
|
+
const [signedTx] = await transact(async (wallet) => {
|
|
468
|
+
await this.reauthorizeWallet(wallet);
|
|
469
|
+
return wallet.signTransactions({ transactions: [tx] });
|
|
470
|
+
}, this.getAssociationConfig());
|
|
471
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
|
|
472
|
+
const signature = await connection.sendRawTransaction(signedTx.serialize(), {
|
|
473
|
+
preflightCommitment: 'confirmed'
|
|
474
|
+
});
|
|
475
|
+
const confirmation = await connection.confirmTransaction({
|
|
476
|
+
signature,
|
|
477
|
+
blockhash,
|
|
478
|
+
lastValidBlockHeight,
|
|
479
|
+
}, 'confirmed');
|
|
480
|
+
if (confirmation.value.err) {
|
|
481
|
+
throw new Error(`Transaction failed: ${confirmation.value.err.toString()}`);
|
|
482
|
+
}
|
|
483
|
+
const txInfo = await connection.getParsedTransaction(signature, {
|
|
484
|
+
maxSupportedTransactionVersion: 0,
|
|
485
|
+
commitment: 'confirmed'
|
|
486
|
+
});
|
|
487
|
+
return {
|
|
488
|
+
transactionSignature: signature,
|
|
489
|
+
blockNumber: (txInfo === null || txInfo === void 0 ? void 0 : txInfo.slot) || 0,
|
|
490
|
+
gasUsed: ((_a = txInfo === null || txInfo === void 0 ? void 0 : txInfo.meta) === null || _a === void 0 ? void 0 : _a.fee.toString()) || '0',
|
|
491
|
+
data: txInfo === null || txInfo === void 0 ? void 0 : txInfo.meta,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
// Non-surfnet: use signAndSendTransactions
|
|
495
|
+
const signatures = await transact(async (wallet) => {
|
|
496
|
+
await this.reauthorizeWallet(wallet);
|
|
497
|
+
return wallet.signAndSendTransactions({
|
|
498
|
+
transactions: [tx],
|
|
499
|
+
commitment: 'confirmed',
|
|
500
|
+
});
|
|
501
|
+
}, this.getAssociationConfig());
|
|
502
|
+
const signature = signatures[0];
|
|
503
|
+
const txInfo = await confirmAndCheckTransaction(connection, signature);
|
|
504
|
+
return {
|
|
505
|
+
transactionSignature: signature,
|
|
506
|
+
blockNumber: (txInfo === null || txInfo === void 0 ? void 0 : txInfo.slot) || 0,
|
|
507
|
+
gasUsed: ((_b = txInfo === null || txInfo === void 0 ? void 0 : txInfo.meta) === null || _b === void 0 ? void 0 : _b.fee.toString()) || '0',
|
|
508
|
+
data: txInfo === null || txInfo === void 0 ? void 0 : txInfo.meta,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
catch (error) {
|
|
512
|
+
if (((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.includes('not connected')) || ((_d = error === null || error === void 0 ? void 0 : error.message) === null || _d === void 0 ? void 0 : _d.includes('not authorized')) ||
|
|
513
|
+
(error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED') {
|
|
514
|
+
await this.logout();
|
|
515
|
+
throw new Error('Wallet connection lost. Please reconnect.');
|
|
516
|
+
}
|
|
517
|
+
const isUserRejection = (error === null || error === void 0 ? void 0 : error.code) === 4001 ||
|
|
518
|
+
((_e = error === null || error === void 0 ? void 0 : error.message) === null || _e === void 0 ? void 0 : _e.toLowerCase().includes('user rejected')) ||
|
|
519
|
+
((_f = error === null || error === void 0 ? void 0 : error.message) === null || _f === void 0 ? void 0 : _f.toLowerCase().includes('user denied')) ||
|
|
520
|
+
((_g = error === null || error === void 0 ? void 0 : error.message) === null || _g === void 0 ? void 0 : _g.toLowerCase().includes('user cancelled')) ||
|
|
521
|
+
((_h = error === null || error === void 0 ? void 0 : error.message) === null || _h === void 0 ? void 0 : _h.toLowerCase().includes('user canceled'));
|
|
522
|
+
if (!isUserRejection) {
|
|
523
|
+
console.error('[SolanaMobileWallet] Transaction failed:', error);
|
|
524
|
+
}
|
|
525
|
+
throw new Error(`Failed to execute transaction: ${error.message}`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
async getNativeMethods() {
|
|
529
|
+
return {
|
|
530
|
+
authToken: this.authToken,
|
|
531
|
+
walletUriBase: this.walletUriBase,
|
|
532
|
+
publicKey: this.publicKeyObj,
|
|
533
|
+
base64Address: this.base64Address,
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
/* ----------------------------------------------------------- *
|
|
537
|
+
* Private Helpers
|
|
538
|
+
* ----------------------------------------------------------- */
|
|
539
|
+
getRpcUrl(network) {
|
|
540
|
+
if (this.networkUrl) {
|
|
541
|
+
return this.networkUrl;
|
|
542
|
+
}
|
|
543
|
+
if (network === 'solana_devnet') {
|
|
544
|
+
return SOLANA_DEVNET_RPC_URL;
|
|
545
|
+
}
|
|
546
|
+
else if (network === 'solana_mainnet') {
|
|
547
|
+
return SOLANA_MAINNET_RPC_URL;
|
|
548
|
+
}
|
|
549
|
+
else if (network === 'surfnet') {
|
|
550
|
+
return SURFNET_RPC_URL;
|
|
551
|
+
}
|
|
552
|
+
return SOLANA_MAINNET_RPC_URL;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
SolanaMobileWalletProvider.instance = null;
|
|
556
|
+
|
|
557
|
+
export { SolanaMobileWalletProvider };
|
|
558
|
+
//# sourceMappingURL=solana-mobile-wallet-provider-BZMvp9Qy.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana-mobile-wallet-provider-BZMvp9Qy.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|