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