@multiplatform.one/web3 7.33.1 → 7.34.0

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.
Files changed (61) hide show
  1. package/README.md +24 -6
  2. package/dist/cjs/phantom/crypto.cjs +108 -0
  3. package/dist/cjs/phantom/crypto.native.js +224 -0
  4. package/dist/cjs/phantom/crypto.native.js.map +1 -0
  5. package/dist/cjs/phantom/index.cjs +16 -1
  6. package/dist/cjs/phantom/index.native.js +16 -1
  7. package/dist/cjs/phantom/index.native.js.map +1 -1
  8. package/dist/cjs/phantom/solana.cjs +309 -0
  9. package/dist/cjs/phantom/solana.native.js +466 -0
  10. package/dist/cjs/phantom/solana.native.js.map +1 -0
  11. package/dist/cjs/phantom/urls.cjs +68 -3
  12. package/dist/cjs/phantom/urls.native.js +92 -4
  13. package/dist/cjs/phantom/urls.native.js.map +1 -1
  14. package/dist/esm/phantom/crypto.mjs +67 -0
  15. package/dist/esm/phantom/crypto.mjs.map +1 -0
  16. package/dist/esm/phantom/crypto.native.js +180 -0
  17. package/dist/esm/phantom/crypto.native.js.map +1 -0
  18. package/dist/esm/phantom/index.mjs +4 -2
  19. package/dist/esm/phantom/index.mjs.map +1 -1
  20. package/dist/esm/phantom/index.native.js +4 -2
  21. package/dist/esm/phantom/index.native.js.map +1 -1
  22. package/dist/esm/phantom/solana.mjs +271 -0
  23. package/dist/esm/phantom/solana.mjs.map +1 -0
  24. package/dist/esm/phantom/solana.native.js +425 -0
  25. package/dist/esm/phantom/solana.native.js.map +1 -0
  26. package/dist/esm/phantom/urls.mjs +53 -3
  27. package/dist/esm/phantom/urls.mjs.map +1 -1
  28. package/dist/esm/phantom/urls.native.js +77 -4
  29. package/dist/esm/phantom/urls.native.js.map +1 -1
  30. package/dist/jsx/phantom/crypto.mjs +67 -0
  31. package/dist/jsx/phantom/crypto.mjs.map +1 -0
  32. package/dist/jsx/phantom/crypto.native.js +224 -0
  33. package/dist/jsx/phantom/crypto.native.js.map +1 -0
  34. package/dist/jsx/phantom/index.mjs +4 -2
  35. package/dist/jsx/phantom/index.mjs.map +1 -1
  36. package/dist/jsx/phantom/index.native.js +16 -1
  37. package/dist/jsx/phantom/index.native.js.map +1 -1
  38. package/dist/jsx/phantom/solana.mjs +271 -0
  39. package/dist/jsx/phantom/solana.mjs.map +1 -0
  40. package/dist/jsx/phantom/solana.native.js +466 -0
  41. package/dist/jsx/phantom/solana.native.js.map +1 -0
  42. package/dist/jsx/phantom/urls.mjs +53 -3
  43. package/dist/jsx/phantom/urls.mjs.map +1 -1
  44. package/dist/jsx/phantom/urls.native.js +92 -4
  45. package/dist/jsx/phantom/urls.native.js.map +1 -1
  46. package/package.json +7 -6
  47. package/src/phantom/crypto.spec.ts +61 -0
  48. package/src/phantom/crypto.ts +88 -0
  49. package/src/phantom/index.ts +38 -5
  50. package/src/phantom/solana.spec.ts +262 -0
  51. package/src/phantom/solana.ts +374 -0
  52. package/src/phantom/urls.spec.ts +101 -10
  53. package/src/phantom/urls.ts +119 -4
  54. package/types/phantom/crypto.d.ts +27 -0
  55. package/types/phantom/crypto.d.ts.map +1 -0
  56. package/types/phantom/index.d.ts +3 -1
  57. package/types/phantom/index.d.ts.map +1 -1
  58. package/types/phantom/solana.d.ts +113 -0
  59. package/types/phantom/solana.d.ts.map +1 -0
  60. package/types/phantom/urls.d.ts +46 -2
  61. package/types/phantom/urls.d.ts.map +1 -1
@@ -0,0 +1,309 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
+ get: () => from[key],
17
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
+ });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
28
+ value: mod,
29
+ enumerable: true
30
+ }) : target, mod));
31
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
32
+ value: true
33
+ }), mod);
34
+ var solana_exports = {};
35
+ __export(solana_exports, {
36
+ PhantomNotConnectedError: () => PhantomNotConnectedError,
37
+ phantomDeeplink: () => phantomDeeplink,
38
+ sendSolanaTransaction: () => sendSolanaTransaction
39
+ });
40
+ module.exports = __toCommonJS(solana_exports);
41
+ var import_bs58 = __toESM(require("bs58"));
42
+ var import_crypto = require("./crypto.cjs");
43
+ var import_urls = require("./urls.cjs");
44
+ class PhantomNotConnectedError extends Error {
45
+ constructor() {
46
+ super("no Phantom deeplink session: call connect() first");
47
+ this.name = "PhantomNotConnectedError";
48
+ }
49
+ }
50
+ const defaultStorageKey = "mpo.web3.phantom.deeplink";
51
+ function defaultStorage() {
52
+ const storage = globalThis.localStorage;
53
+ if (!storage) throw new Error("phantomDeeplink: no localStorage here; pass `storage`");
54
+ return storage;
55
+ }
56
+ function currentHref() {
57
+ const href = globalThis.location?.href;
58
+ if (!href) throw new Error("phantomDeeplink: no location here; pass `redirectLink`");
59
+ return href;
60
+ }
61
+ function phantomDeeplink(config) {
62
+ const storageKey = config.storageKey ?? defaultStorageKey;
63
+ const storage = () => config.storage ?? defaultStorage();
64
+ const now = config.now ?? Date.now;
65
+ const navigate = config.navigate ?? (url => globalThis.location.assign(url));
66
+ const redirectLink = () => config.redirectLink ?? (0, import_urls.stripPhantomRedirect)(currentHref());
67
+ const load = () => {
68
+ const raw = storage().getItem(storageKey);
69
+ if (!raw) return void 0;
70
+ try {
71
+ return JSON.parse(raw);
72
+ } catch {
73
+ return void 0;
74
+ }
75
+ };
76
+ const save = record => storage().setItem(storageKey, JSON.stringify(record));
77
+ const connected = () => {
78
+ const record = load();
79
+ if (!record?.session || !record.phantomEncryptionPublicKey) throw new PhantomNotConnectedError();
80
+ return record;
81
+ };
82
+ const methodUrl = (record, method, payload) => {
83
+ const keyPair = (0, import_crypto.boxKeyPairFromSecretKey)(import_bs58.default.decode(record.dappSecretKey));
84
+ return (0, import_urls.phantomMethodUrl)({
85
+ method,
86
+ payload,
87
+ session: record.session,
88
+ dappEncryptionPublicKey: keyPair.publicKey,
89
+ sharedSecret: (0, import_crypto.sharedSecret)(import_bs58.default.decode(record.phantomEncryptionPublicKey), keyPair.secretKey),
90
+ redirectLink: redirectLink(),
91
+ base: config.base
92
+ });
93
+ };
94
+ const request = (method, payload) => {
95
+ const record = connected();
96
+ const url = methodUrl(record, method, payload);
97
+ save({
98
+ ...record,
99
+ pending: {
100
+ method,
101
+ at: now()
102
+ }
103
+ });
104
+ navigate(url);
105
+ return url;
106
+ };
107
+ return {
108
+ get publicKey() {
109
+ return load()?.publicKey;
110
+ },
111
+ get connected() {
112
+ const record = load();
113
+ return !!(record?.session && record.phantomEncryptionPublicKey);
114
+ },
115
+ get pending() {
116
+ return load()?.pending;
117
+ },
118
+ connect() {
119
+ const keyPair = (0, import_crypto.generateBoxKeyPair)();
120
+ const url = (0, import_urls.phantomConnectUrl)({
121
+ appUrl: config.appUrl,
122
+ dappEncryptionPublicKey: keyPair.publicKey,
123
+ redirectLink: redirectLink(),
124
+ cluster: config.cluster,
125
+ base: config.base
126
+ });
127
+ save({
128
+ dappSecretKey: import_bs58.default.encode(keyPair.secretKey),
129
+ cluster: config.cluster,
130
+ pending: {
131
+ method: "connect",
132
+ at: now()
133
+ }
134
+ });
135
+ navigate(url);
136
+ return url;
137
+ },
138
+ signTransaction(serializedTransaction) {
139
+ return request("signTransaction", {
140
+ transaction: import_bs58.default.encode(serializedTransaction)
141
+ });
142
+ },
143
+ signAllTransactions(serializedTransactions) {
144
+ return request("signAllTransactions", {
145
+ transactions: serializedTransactions.map(tx => import_bs58.default.encode(tx))
146
+ });
147
+ },
148
+ signAndSendTransaction(serializedTransaction, sendOptions) {
149
+ return request("signAndSendTransaction", {
150
+ transaction: import_bs58.default.encode(serializedTransaction),
151
+ ...(sendOptions ? {
152
+ sendOptions
153
+ } : {})
154
+ });
155
+ },
156
+ signMessage(message, display) {
157
+ const bytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
158
+ return request("signMessage", {
159
+ message: import_bs58.default.encode(bytes),
160
+ ...(display ? {
161
+ display
162
+ } : {})
163
+ });
164
+ },
165
+ disconnect() {
166
+ const url = methodUrl(connected(), "disconnect", {});
167
+ storage().removeItem(storageKey);
168
+ navigate(url);
169
+ return url;
170
+ },
171
+ handleRedirect(href) {
172
+ const params = (0, import_urls.parsePhantomRedirect)(href ?? currentHref());
173
+ if (!params) return void 0;
174
+ const record = load();
175
+ const method = record?.pending?.method;
176
+ if (params.errorCode) {
177
+ if (record) save({
178
+ ...record,
179
+ pending: void 0
180
+ });
181
+ return {
182
+ ok: false,
183
+ method,
184
+ errorCode: params.errorCode,
185
+ errorMessage: params.errorMessage ?? ""
186
+ };
187
+ }
188
+ if (!record || !params.data || !params.nonce) {
189
+ return {
190
+ ok: false,
191
+ method,
192
+ errorCode: "-32603",
193
+ errorMessage: "Phantom answered, but this browser holds no matching request"
194
+ };
195
+ }
196
+ const secretKey = import_bs58.default.decode(record.dappSecretKey);
197
+ const phantomKey = method === "connect" ? params.phantomEncryptionPublicKey : record.phantomEncryptionPublicKey;
198
+ if (!phantomKey) {
199
+ return {
200
+ ok: false,
201
+ method,
202
+ errorCode: "-32603",
203
+ errorMessage: "Phantom's answer carries no encryption key"
204
+ };
205
+ }
206
+ const data = (0, import_crypto.decryptPayload)(params.data, params.nonce, (0, import_crypto.sharedSecret)(import_bs58.default.decode(phantomKey), secretKey));
207
+ switch (method) {
208
+ case "connect":
209
+ {
210
+ const publicKey = String(data.public_key);
211
+ const session = String(data.session);
212
+ save({
213
+ ...record,
214
+ phantomEncryptionPublicKey: phantomKey,
215
+ publicKey,
216
+ session,
217
+ pending: void 0
218
+ });
219
+ return {
220
+ ok: true,
221
+ method,
222
+ publicKey,
223
+ session
224
+ };
225
+ }
226
+ case "signTransaction":
227
+ save({
228
+ ...record,
229
+ pending: void 0
230
+ });
231
+ return {
232
+ ok: true,
233
+ method,
234
+ transaction: import_bs58.default.decode(String(data.transaction))
235
+ };
236
+ case "signAllTransactions":
237
+ save({
238
+ ...record,
239
+ pending: void 0
240
+ });
241
+ return {
242
+ ok: true,
243
+ method,
244
+ transactions: data.transactions.map(tx => import_bs58.default.decode(tx))
245
+ };
246
+ case "signAndSendTransaction":
247
+ save({
248
+ ...record,
249
+ pending: void 0
250
+ });
251
+ return {
252
+ ok: true,
253
+ method,
254
+ signature: String(data.signature)
255
+ };
256
+ case "signMessage":
257
+ save({
258
+ ...record,
259
+ pending: void 0
260
+ });
261
+ return {
262
+ ok: true,
263
+ method,
264
+ signature: import_bs58.default.decode(String(data.signature))
265
+ };
266
+ default:
267
+ return {
268
+ ok: false,
269
+ method,
270
+ errorCode: "-32603",
271
+ errorMessage: "Phantom answered a request this browser did not make"
272
+ };
273
+ }
274
+ },
275
+ forget() {
276
+ storage().removeItem(storageKey);
277
+ }
278
+ };
279
+ }
280
+ function toBase64(bytes) {
281
+ let binary = "";
282
+ for (const byte of bytes) binary += String.fromCharCode(byte);
283
+ return btoa(binary);
284
+ }
285
+ async function sendSolanaTransaction(rpcUrl, signedTransaction, options = {}) {
286
+ const response = await (options.fetch ?? fetch)(rpcUrl, {
287
+ method: "POST",
288
+ headers: {
289
+ "content-type": "application/json"
290
+ },
291
+ body: JSON.stringify({
292
+ jsonrpc: "2.0",
293
+ id: 1,
294
+ method: "sendTransaction",
295
+ params: [toBase64(signedTransaction), {
296
+ encoding: "base64",
297
+ skipPreflight: options.skipPreflight ?? false
298
+ }]
299
+ })
300
+ });
301
+ const body = await response.json();
302
+ if (body.error) {
303
+ throw Object.assign(new Error(`sendTransaction failed: ${body.error.message}`), {
304
+ code: body.error.code
305
+ });
306
+ }
307
+ if (typeof body.result !== "string") throw new Error("sendTransaction returned no signature");
308
+ return body.result;
309
+ }