@column-org/wallet-sdk 1.0.0 → 1.1.1

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/index.d.mts CHANGED
@@ -8,6 +8,7 @@ interface ColumnSDKConfig {
8
8
  appDescription?: string;
9
9
  walletScheme?: string;
10
10
  network?: string;
11
+ sessionSecretKey?: string;
11
12
  }
12
13
  declare class ColumnCrypto {
13
14
  static generateKeyPair(): nacl.BoxKeyPair;
@@ -22,13 +23,15 @@ declare class ColumnWalletSDK {
22
23
  private config;
23
24
  private sessionKeyPair;
24
25
  private walletEncryptionPublicKey;
25
- private modal;
26
26
  constructor(config: ColumnSDKConfig);
27
- private autoDetectMetadata;
28
27
  /**
29
- * Opens the premium Column selection modal
28
+ * Returns the current session's secret key (bs58) so it can be persisted
30
29
  */
31
- openConnectModal(): void;
30
+ getSessionSecretKey(): string;
31
+ /**
32
+ * Internal: Used by Web/Native adapters to get the config
33
+ */
34
+ getConfig(): ColumnSDKConfig;
32
35
  setWalletEncryptionPublicKey(key: string): void;
33
36
  /**
34
37
  * Alias for setWalletEncryptionPublicKey to match docs
@@ -56,4 +59,14 @@ declare class ColumnWalletSDK {
56
59
  setWalletPublicKey(publicKeyB58: string): void;
57
60
  }
58
61
 
59
- export { ColumnCrypto, type ColumnSDKConfig, ColumnWalletSDK };
62
+ /**
63
+ * Enhanced SDK Class specifically for Web environments
64
+ */
65
+ declare class ColumnWalletWeb extends ColumnWalletSDK {
66
+ private modal;
67
+ constructor(config: ColumnSDKConfig);
68
+ private static autoDetectMetadata;
69
+ openConnectModal(): void;
70
+ }
71
+
72
+ export { ColumnCrypto, type ColumnSDKConfig, ColumnWalletSDK, ColumnWalletWeb };
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ interface ColumnSDKConfig {
8
8
  appDescription?: string;
9
9
  walletScheme?: string;
10
10
  network?: string;
11
+ sessionSecretKey?: string;
11
12
  }
12
13
  declare class ColumnCrypto {
13
14
  static generateKeyPair(): nacl.BoxKeyPair;
@@ -22,13 +23,15 @@ declare class ColumnWalletSDK {
22
23
  private config;
23
24
  private sessionKeyPair;
24
25
  private walletEncryptionPublicKey;
25
- private modal;
26
26
  constructor(config: ColumnSDKConfig);
27
- private autoDetectMetadata;
28
27
  /**
29
- * Opens the premium Column selection modal
28
+ * Returns the current session's secret key (bs58) so it can be persisted
30
29
  */
31
- openConnectModal(): void;
30
+ getSessionSecretKey(): string;
31
+ /**
32
+ * Internal: Used by Web/Native adapters to get the config
33
+ */
34
+ getConfig(): ColumnSDKConfig;
32
35
  setWalletEncryptionPublicKey(key: string): void;
33
36
  /**
34
37
  * Alias for setWalletEncryptionPublicKey to match docs
@@ -56,4 +59,14 @@ declare class ColumnWalletSDK {
56
59
  setWalletPublicKey(publicKeyB58: string): void;
57
60
  }
58
61
 
59
- export { ColumnCrypto, type ColumnSDKConfig, ColumnWalletSDK };
62
+ /**
63
+ * Enhanced SDK Class specifically for Web environments
64
+ */
65
+ declare class ColumnWalletWeb extends ColumnWalletSDK {
66
+ private modal;
67
+ constructor(config: ColumnSDKConfig);
68
+ private static autoDetectMetadata;
69
+ openConnectModal(): void;
70
+ }
71
+
72
+ export { ColumnCrypto, type ColumnSDKConfig, ColumnWalletSDK, ColumnWalletWeb };
package/dist/index.js CHANGED
@@ -31,7 +31,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  ColumnCrypto: () => ColumnCrypto,
34
- ColumnWalletSDK: () => ColumnWalletSDK
34
+ ColumnWalletSDK: () => ColumnWalletSDK,
35
+ ColumnWalletWeb: () => ColumnWalletWeb
35
36
  });
36
37
  module.exports = __toCommonJS(index_exports);
37
38
 
@@ -70,8 +71,210 @@ var ColumnCrypto = class {
70
71
  sharedSecret
71
72
  );
72
73
  if (!decrypted) return null;
73
- const jsonString = import_buffer.Buffer.from(decrypted).toString("utf8");
74
- return JSON.parse(jsonString);
74
+ try {
75
+ const jsonString = import_buffer.Buffer.from(decrypted).toString("utf8");
76
+ return JSON.parse(jsonString);
77
+ } catch (e) {
78
+ console.error("ColumnCrypto: Failed to parse decrypted payload", e);
79
+ return null;
80
+ }
81
+ }
82
+ };
83
+
84
+ // src/ColumnWalletSDK.ts
85
+ var nacl2 = __toESM(require("tweetnacl"));
86
+ var ColumnWalletSDK = class {
87
+ config;
88
+ sessionKeyPair;
89
+ walletEncryptionPublicKey = null;
90
+ constructor(config) {
91
+ this.config = config;
92
+ if (config.sessionSecretKey) {
93
+ try {
94
+ const secretKey = import_bs582.default.decode(config.sessionSecretKey);
95
+ this.sessionKeyPair = nacl2.box.keyPair.fromSecretKey(secretKey);
96
+ } catch (e) {
97
+ console.warn("ColumnWalletSDK: Invalid sessionSecretKey provided, generating new one.");
98
+ this.sessionKeyPair = ColumnCrypto.generateKeyPair();
99
+ }
100
+ } else {
101
+ this.sessionKeyPair = ColumnCrypto.generateKeyPair();
102
+ }
103
+ }
104
+ /**
105
+ * Returns the current session's secret key (bs58) so it can be persisted
106
+ */
107
+ getSessionSecretKey() {
108
+ return import_bs582.default.encode(this.sessionKeyPair.secretKey);
109
+ }
110
+ /**
111
+ * Internal: Used by Web/Native adapters to get the config
112
+ */
113
+ getConfig() {
114
+ return this.config;
115
+ }
116
+ setWalletEncryptionPublicKey(key) {
117
+ this.walletEncryptionPublicKey = key;
118
+ }
119
+ /**
120
+ * Alias for setWalletEncryptionPublicKey to match docs
121
+ */
122
+ importWalletKey(key) {
123
+ this.setWalletEncryptionPublicKey(key);
124
+ }
125
+ /**
126
+ * Step 1: Connect to the wallet
127
+ */
128
+ connect() {
129
+ const params = new URLSearchParams({
130
+ request: "connect",
131
+ app_url: this.config.appUrl || "",
132
+ app_name: this.config.appName || "",
133
+ dapp_encryption_public_key: import_bs582.default.encode(this.sessionKeyPair.publicKey),
134
+ redirect_link: this.config.redirectLink || ""
135
+ });
136
+ if (this.config.appIcon) {
137
+ params.append("app_icon", this.config.appIcon);
138
+ }
139
+ if (this.config.network) {
140
+ params.append("network", this.config.network);
141
+ }
142
+ if (this.config.appDescription) {
143
+ params.append("app_description", this.config.appDescription);
144
+ }
145
+ const scheme = this.config.walletScheme || "column";
146
+ const base = scheme.includes("://") ? scheme : `${scheme}://`;
147
+ return `${base}${base.endsWith("/") ? "" : "/"}?${params.toString()}`;
148
+ }
149
+ /**
150
+ * Step 2: Sign and Submit a transaction
151
+ */
152
+ signAndSubmitTransaction(transaction) {
153
+ if (!this.walletEncryptionPublicKey) {
154
+ throw new Error("Wallet not connected. Call connect() first and store the wallet_encryption_public_key.");
155
+ }
156
+ const payload = {
157
+ transaction
158
+ };
159
+ const encrypted = ColumnCrypto.encryptPayload(
160
+ payload,
161
+ this.walletEncryptionPublicKey,
162
+ this.sessionKeyPair.secretKey
163
+ );
164
+ const params = new URLSearchParams({
165
+ request: "signAndSubmitTransaction",
166
+ app_url: this.config.appUrl || "",
167
+ app_name: this.config.appName || "",
168
+ dapp_encryption_public_key: import_bs582.default.encode(this.sessionKeyPair.publicKey),
169
+ data: encrypted.data,
170
+ nonce: encrypted.nonce,
171
+ redirect_link: this.config.redirectLink || ""
172
+ });
173
+ if (this.config.appIcon) {
174
+ params.append("app_icon", this.config.appIcon);
175
+ }
176
+ if (this.config.network) {
177
+ params.append("network", this.config.network);
178
+ }
179
+ if (this.config.appDescription) {
180
+ params.append("app_description", this.config.appDescription);
181
+ }
182
+ const scheme = this.config.walletScheme || "column";
183
+ const base = scheme.includes("://") ? scheme : `${scheme}://`;
184
+ return `${base}${base.endsWith("/") ? "" : "/"}?${params.toString()}`;
185
+ }
186
+ /**
187
+ * Step 3: Sign a simple message
188
+ */
189
+ signMessage(message) {
190
+ if (!this.walletEncryptionPublicKey) {
191
+ throw new Error("Wallet not connected.");
192
+ }
193
+ const payload = {
194
+ message
195
+ };
196
+ const encrypted = ColumnCrypto.encryptPayload(
197
+ payload,
198
+ this.walletEncryptionPublicKey,
199
+ this.sessionKeyPair.secretKey
200
+ );
201
+ const params = new URLSearchParams({
202
+ request: "signMessage",
203
+ app_url: this.config.appUrl || "",
204
+ app_name: this.config.appName || "",
205
+ dapp_encryption_public_key: import_bs582.default.encode(this.sessionKeyPair.publicKey),
206
+ data: encrypted.data,
207
+ nonce: encrypted.nonce,
208
+ redirect_link: this.config.redirectLink || ""
209
+ });
210
+ if (this.config.appIcon) {
211
+ params.append("app_icon", this.config.appIcon);
212
+ }
213
+ if (this.config.network) {
214
+ params.append("network", this.config.network);
215
+ }
216
+ if (this.config.appDescription) {
217
+ params.append("app_description", this.config.appDescription);
218
+ }
219
+ const scheme = this.config.walletScheme || "column";
220
+ const base = scheme.includes("://") ? scheme : `${scheme}://`;
221
+ return `${base}${base.endsWith("/") ? "" : "/"}?${params.toString()}`;
222
+ }
223
+ /**
224
+ * Utility: Parse the response from Column
225
+ */
226
+ handleResponse(url) {
227
+ let params;
228
+ try {
229
+ const urlObj = new URL(url.includes("://") ? url : `http://localhost/${url}`);
230
+ const hashStr = urlObj.hash.substring(1);
231
+ const searchStr = urlObj.search.substring(1);
232
+ if (hashStr) {
233
+ params = new URLSearchParams(hashStr);
234
+ } else {
235
+ params = new URLSearchParams(searchStr);
236
+ }
237
+ } catch (e) {
238
+ const hashMatch = url.match(/#(.*)$/);
239
+ const queryMatch = url.match(/\?(.*)$/);
240
+ params = new URLSearchParams(hashMatch ? hashMatch[1] : queryMatch ? queryMatch[1] : url);
241
+ }
242
+ const data = params.get("data");
243
+ const nonce = params.get("nonce");
244
+ const error = params.get("error");
245
+ if (error) {
246
+ throw new Error(`Column Wallet Error: ${error}`);
247
+ }
248
+ if (data && nonce && this.walletEncryptionPublicKey) {
249
+ const decrypted = ColumnCrypto.decryptPayload(
250
+ data,
251
+ nonce,
252
+ this.walletEncryptionPublicKey,
253
+ this.sessionKeyPair.secretKey
254
+ );
255
+ if (!decrypted) {
256
+ throw new Error("Column Wallet Error: Decryption failed. The response may have been tampered with or keys do not match.");
257
+ }
258
+ return {
259
+ ...decrypted,
260
+ network: params.get("network")
261
+ // Always include network from URL
262
+ };
263
+ }
264
+ const response = {};
265
+ params.forEach((value, key) => {
266
+ response[key] = value;
267
+ });
268
+ if (response.column_encryption_public_key) {
269
+ this.walletEncryptionPublicKey = response.column_encryption_public_key;
270
+ }
271
+ return response;
272
+ }
273
+ /**
274
+ * Sets the wallet's public key if known from a previous session
275
+ */
276
+ setWalletPublicKey(publicKeyB58) {
277
+ this.walletEncryptionPublicKey = publicKeyB58;
75
278
  }
76
279
  };
77
280
 
@@ -210,7 +413,7 @@ var ColumnConnectModal = class {
210
413
  document.head.appendChild(styleTag);
211
414
  }
212
415
  open() {
213
- if (typeof document === "undefined") return;
416
+ if (typeof document === "undefined" || this.overlay) return;
214
417
  this.overlay = document.createElement("div");
215
418
  this.overlay.className = "column-modal-overlay";
216
419
  this.overlay.innerHTML = `
@@ -257,218 +460,31 @@ var ColumnConnectModal = class {
257
460
  }
258
461
  };
259
462
 
260
- // src/ColumnWalletSDK.ts
261
- var ColumnWalletSDK = class {
262
- config;
263
- sessionKeyPair;
264
- walletEncryptionPublicKey = null;
463
+ // src/ui/ColumnWalletWeb.ts
464
+ var ColumnWalletWeb = class _ColumnWalletWeb extends ColumnWalletSDK {
265
465
  modal;
266
466
  constructor(config) {
267
- this.config = this.autoDetectMetadata(config);
268
- this.sessionKeyPair = ColumnCrypto.generateKeyPair();
467
+ const detectedConfig = _ColumnWalletWeb.autoDetectMetadata(config);
468
+ super(detectedConfig);
269
469
  this.modal = new ColumnConnectModal(() => {
270
470
  window.location.href = this.connect();
271
471
  });
272
472
  }
273
- autoDetectMetadata(config) {
473
+ static autoDetectMetadata(config) {
274
474
  if (typeof document === "undefined") return config;
275
475
  const detectedConfig = { ...config };
276
- if (!detectedConfig.appUrl) {
277
- detectedConfig.appUrl = window.location.origin;
278
- }
279
- if (!detectedConfig.appName) {
280
- detectedConfig.appName = document.title || "Unknown dApp";
281
- }
282
- if (!detectedConfig.appIcon) {
283
- const iconLink = document.querySelector('link[rel~="icon"]') || document.querySelector('link[rel="apple-touch-icon"]');
284
- if (iconLink) {
285
- try {
286
- detectedConfig.appIcon = new URL(iconLink.getAttribute("href") || "", window.location.origin).href;
287
- } catch (e) {
288
- detectedConfig.appIcon = iconLink.href;
289
- }
290
- }
291
- }
292
- if (!detectedConfig.appDescription) {
293
- const metaDescription = document.querySelector('meta[name="description"]') || document.querySelector('meta[property="og:description"]');
294
- if (metaDescription?.content) {
295
- detectedConfig.appDescription = metaDescription.content;
296
- }
297
- }
298
- if (!detectedConfig.redirectLink) {
299
- detectedConfig.redirectLink = window.location.href.split("?")[0];
300
- }
476
+ if (!detectedConfig.appUrl) detectedConfig.appUrl = window.location.origin;
477
+ if (!detectedConfig.appName) detectedConfig.appName = document.title || "Unknown dApp";
478
+ if (!detectedConfig.redirectLink) detectedConfig.redirectLink = window.location.href.split("?")[0];
301
479
  return detectedConfig;
302
480
  }
303
- /**
304
- * Opens the premium Column selection modal
305
- */
306
481
  openConnectModal() {
307
482
  this.modal.open();
308
483
  }
309
- setWalletEncryptionPublicKey(key) {
310
- this.walletEncryptionPublicKey = key;
311
- }
312
- /**
313
- * Alias for setWalletEncryptionPublicKey to match docs
314
- */
315
- importWalletKey(key) {
316
- this.setWalletEncryptionPublicKey(key);
317
- }
318
- /**
319
- * Step 1: Connect to the wallet
320
- */
321
- connect() {
322
- const params = new URLSearchParams({
323
- request: "connect",
324
- app_url: this.config.appUrl || "",
325
- app_name: this.config.appName || "",
326
- dapp_encryption_public_key: import_bs582.default.encode(this.sessionKeyPair.publicKey),
327
- redirect_link: this.config.redirectLink || ""
328
- });
329
- if (this.config.appIcon) {
330
- params.append("app_icon", this.config.appIcon);
331
- }
332
- if (this.config.network) {
333
- params.append("network", this.config.network);
334
- }
335
- if (this.config.appDescription) {
336
- params.append("app_description", this.config.appDescription);
337
- }
338
- const scheme = this.config.walletScheme || "column";
339
- const base = scheme.includes("://") ? scheme : `${scheme}://`;
340
- return `${base}${base.endsWith("/") ? "" : "/"}?${params.toString()}`;
341
- }
342
- /**
343
- * Step 2: Sign and Submit a transaction
344
- */
345
- signAndSubmitTransaction(transaction) {
346
- if (!this.walletEncryptionPublicKey) {
347
- throw new Error("Wallet not connected. Call connect() first and store the wallet_encryption_public_key.");
348
- }
349
- const payload = {
350
- transaction
351
- };
352
- const encrypted = ColumnCrypto.encryptPayload(
353
- payload,
354
- this.walletEncryptionPublicKey,
355
- this.sessionKeyPair.secretKey
356
- );
357
- const params = new URLSearchParams({
358
- request: "signAndSubmitTransaction",
359
- app_url: this.config.appUrl || "",
360
- app_name: this.config.appName || "",
361
- dapp_encryption_public_key: import_bs582.default.encode(this.sessionKeyPair.publicKey),
362
- data: encrypted.data,
363
- nonce: encrypted.nonce,
364
- redirect_link: this.config.redirectLink || ""
365
- });
366
- if (this.config.appIcon) {
367
- params.append("app_icon", this.config.appIcon);
368
- }
369
- if (this.config.network) {
370
- params.append("network", this.config.network);
371
- }
372
- if (this.config.appDescription) {
373
- params.append("app_description", this.config.appDescription);
374
- }
375
- const scheme = this.config.walletScheme || "column";
376
- const base = scheme.includes("://") ? scheme : `${scheme}://`;
377
- return `${base}${base.endsWith("/") ? "" : "/"}?${params.toString()}`;
378
- }
379
- /**
380
- * Step 3: Sign a simple message
381
- */
382
- signMessage(message) {
383
- if (!this.walletEncryptionPublicKey) {
384
- throw new Error("Wallet not connected.");
385
- }
386
- const payload = {
387
- message
388
- };
389
- const encrypted = ColumnCrypto.encryptPayload(
390
- payload,
391
- this.walletEncryptionPublicKey,
392
- this.sessionKeyPair.secretKey
393
- );
394
- const params = new URLSearchParams({
395
- request: "signMessage",
396
- app_url: this.config.appUrl || "",
397
- app_name: this.config.appName || "",
398
- dapp_encryption_public_key: import_bs582.default.encode(this.sessionKeyPair.publicKey),
399
- data: encrypted.data,
400
- nonce: encrypted.nonce,
401
- redirect_link: this.config.redirectLink || ""
402
- });
403
- if (this.config.appIcon) {
404
- params.append("app_icon", this.config.appIcon);
405
- }
406
- if (this.config.network) {
407
- params.append("network", this.config.network);
408
- }
409
- if (this.config.appDescription) {
410
- params.append("app_description", this.config.appDescription);
411
- }
412
- const scheme = this.config.walletScheme || "column";
413
- const base = scheme.includes("://") ? scheme : `${scheme}://`;
414
- return `${base}${base.endsWith("/") ? "" : "/"}?${params.toString()}`;
415
- }
416
- /**
417
- * Utility: Parse the response from Column
418
- */
419
- handleResponse(url) {
420
- let params;
421
- try {
422
- const urlObj = new URL(url.includes("://") ? url : `http://localhost/${url}`);
423
- const hashStr = urlObj.hash.substring(1);
424
- const searchStr = urlObj.search.substring(1);
425
- if (hashStr) {
426
- params = new URLSearchParams(hashStr);
427
- } else {
428
- params = new URLSearchParams(searchStr);
429
- }
430
- } catch (e) {
431
- const hashMatch = url.match(/#(.*)$/);
432
- const queryMatch = url.match(/\?(.*)$/);
433
- params = new URLSearchParams(hashMatch ? hashMatch[1] : queryMatch ? queryMatch[1] : url);
434
- }
435
- const data = params.get("data");
436
- const nonce = params.get("nonce");
437
- const error = params.get("error");
438
- if (error) {
439
- throw new Error(`Column Wallet Error: ${error}`);
440
- }
441
- if (data && nonce && this.walletEncryptionPublicKey) {
442
- const decrypted = ColumnCrypto.decryptPayload(
443
- data,
444
- nonce,
445
- this.walletEncryptionPublicKey,
446
- this.sessionKeyPair.secretKey
447
- );
448
- return {
449
- ...decrypted,
450
- network: params.get("network")
451
- // Always include network from URL
452
- };
453
- }
454
- const response = {};
455
- params.forEach((value, key) => {
456
- response[key] = value;
457
- });
458
- if (response.column_encryption_public_key) {
459
- this.walletEncryptionPublicKey = response.column_encryption_public_key;
460
- }
461
- return response;
462
- }
463
- /**
464
- * Sets the wallet's public key if known from a previous session
465
- */
466
- setWalletPublicKey(publicKeyB58) {
467
- this.walletEncryptionPublicKey = publicKeyB58;
468
- }
469
484
  };
470
485
  // Annotate the CommonJS export names for ESM import in node:
471
486
  0 && (module.exports = {
472
487
  ColumnCrypto,
473
- ColumnWalletSDK
488
+ ColumnWalletSDK,
489
+ ColumnWalletWeb
474
490
  });