@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 +18 -5
- package/dist/index.d.ts +18 -5
- package/dist/index.js +217 -201
- package/dist/index.mjs +215 -200
- package/package.json +5 -2
- package/src/ColumnShared.ts +69 -0
- package/src/ColumnWalletSDK.ts +236 -0
- package/src/assets/Column.png +0 -0
- package/src/index.native.ts +10 -0
- package/src/index.ts +3 -0
- package/src/ui/ColumnConnectModal.ts +199 -0
- package/src/ui/ColumnWalletWeb.ts +34 -0
package/dist/index.mjs
CHANGED
|
@@ -33,8 +33,210 @@ var ColumnCrypto = class {
|
|
|
33
33
|
sharedSecret
|
|
34
34
|
);
|
|
35
35
|
if (!decrypted) return null;
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
try {
|
|
37
|
+
const jsonString = Buffer.from(decrypted).toString("utf8");
|
|
38
|
+
return JSON.parse(jsonString);
|
|
39
|
+
} catch (e) {
|
|
40
|
+
console.error("ColumnCrypto: Failed to parse decrypted payload", e);
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// src/ColumnWalletSDK.ts
|
|
47
|
+
import * as nacl2 from "tweetnacl";
|
|
48
|
+
var ColumnWalletSDK = class {
|
|
49
|
+
config;
|
|
50
|
+
sessionKeyPair;
|
|
51
|
+
walletEncryptionPublicKey = null;
|
|
52
|
+
constructor(config) {
|
|
53
|
+
this.config = config;
|
|
54
|
+
if (config.sessionSecretKey) {
|
|
55
|
+
try {
|
|
56
|
+
const secretKey = bs582.decode(config.sessionSecretKey);
|
|
57
|
+
this.sessionKeyPair = nacl2.box.keyPair.fromSecretKey(secretKey);
|
|
58
|
+
} catch (e) {
|
|
59
|
+
console.warn("ColumnWalletSDK: Invalid sessionSecretKey provided, generating new one.");
|
|
60
|
+
this.sessionKeyPair = ColumnCrypto.generateKeyPair();
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
this.sessionKeyPair = ColumnCrypto.generateKeyPair();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Returns the current session's secret key (bs58) so it can be persisted
|
|
68
|
+
*/
|
|
69
|
+
getSessionSecretKey() {
|
|
70
|
+
return bs582.encode(this.sessionKeyPair.secretKey);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Internal: Used by Web/Native adapters to get the config
|
|
74
|
+
*/
|
|
75
|
+
getConfig() {
|
|
76
|
+
return this.config;
|
|
77
|
+
}
|
|
78
|
+
setWalletEncryptionPublicKey(key) {
|
|
79
|
+
this.walletEncryptionPublicKey = key;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Alias for setWalletEncryptionPublicKey to match docs
|
|
83
|
+
*/
|
|
84
|
+
importWalletKey(key) {
|
|
85
|
+
this.setWalletEncryptionPublicKey(key);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Step 1: Connect to the wallet
|
|
89
|
+
*/
|
|
90
|
+
connect() {
|
|
91
|
+
const params = new URLSearchParams({
|
|
92
|
+
request: "connect",
|
|
93
|
+
app_url: this.config.appUrl || "",
|
|
94
|
+
app_name: this.config.appName || "",
|
|
95
|
+
dapp_encryption_public_key: bs582.encode(this.sessionKeyPair.publicKey),
|
|
96
|
+
redirect_link: this.config.redirectLink || ""
|
|
97
|
+
});
|
|
98
|
+
if (this.config.appIcon) {
|
|
99
|
+
params.append("app_icon", this.config.appIcon);
|
|
100
|
+
}
|
|
101
|
+
if (this.config.network) {
|
|
102
|
+
params.append("network", this.config.network);
|
|
103
|
+
}
|
|
104
|
+
if (this.config.appDescription) {
|
|
105
|
+
params.append("app_description", this.config.appDescription);
|
|
106
|
+
}
|
|
107
|
+
const scheme = this.config.walletScheme || "column";
|
|
108
|
+
const base = scheme.includes("://") ? scheme : `${scheme}://`;
|
|
109
|
+
return `${base}${base.endsWith("/") ? "" : "/"}?${params.toString()}`;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Step 2: Sign and Submit a transaction
|
|
113
|
+
*/
|
|
114
|
+
signAndSubmitTransaction(transaction) {
|
|
115
|
+
if (!this.walletEncryptionPublicKey) {
|
|
116
|
+
throw new Error("Wallet not connected. Call connect() first and store the wallet_encryption_public_key.");
|
|
117
|
+
}
|
|
118
|
+
const payload = {
|
|
119
|
+
transaction
|
|
120
|
+
};
|
|
121
|
+
const encrypted = ColumnCrypto.encryptPayload(
|
|
122
|
+
payload,
|
|
123
|
+
this.walletEncryptionPublicKey,
|
|
124
|
+
this.sessionKeyPair.secretKey
|
|
125
|
+
);
|
|
126
|
+
const params = new URLSearchParams({
|
|
127
|
+
request: "signAndSubmitTransaction",
|
|
128
|
+
app_url: this.config.appUrl || "",
|
|
129
|
+
app_name: this.config.appName || "",
|
|
130
|
+
dapp_encryption_public_key: bs582.encode(this.sessionKeyPair.publicKey),
|
|
131
|
+
data: encrypted.data,
|
|
132
|
+
nonce: encrypted.nonce,
|
|
133
|
+
redirect_link: this.config.redirectLink || ""
|
|
134
|
+
});
|
|
135
|
+
if (this.config.appIcon) {
|
|
136
|
+
params.append("app_icon", this.config.appIcon);
|
|
137
|
+
}
|
|
138
|
+
if (this.config.network) {
|
|
139
|
+
params.append("network", this.config.network);
|
|
140
|
+
}
|
|
141
|
+
if (this.config.appDescription) {
|
|
142
|
+
params.append("app_description", this.config.appDescription);
|
|
143
|
+
}
|
|
144
|
+
const scheme = this.config.walletScheme || "column";
|
|
145
|
+
const base = scheme.includes("://") ? scheme : `${scheme}://`;
|
|
146
|
+
return `${base}${base.endsWith("/") ? "" : "/"}?${params.toString()}`;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Step 3: Sign a simple message
|
|
150
|
+
*/
|
|
151
|
+
signMessage(message) {
|
|
152
|
+
if (!this.walletEncryptionPublicKey) {
|
|
153
|
+
throw new Error("Wallet not connected.");
|
|
154
|
+
}
|
|
155
|
+
const payload = {
|
|
156
|
+
message
|
|
157
|
+
};
|
|
158
|
+
const encrypted = ColumnCrypto.encryptPayload(
|
|
159
|
+
payload,
|
|
160
|
+
this.walletEncryptionPublicKey,
|
|
161
|
+
this.sessionKeyPair.secretKey
|
|
162
|
+
);
|
|
163
|
+
const params = new URLSearchParams({
|
|
164
|
+
request: "signMessage",
|
|
165
|
+
app_url: this.config.appUrl || "",
|
|
166
|
+
app_name: this.config.appName || "",
|
|
167
|
+
dapp_encryption_public_key: bs582.encode(this.sessionKeyPair.publicKey),
|
|
168
|
+
data: encrypted.data,
|
|
169
|
+
nonce: encrypted.nonce,
|
|
170
|
+
redirect_link: this.config.redirectLink || ""
|
|
171
|
+
});
|
|
172
|
+
if (this.config.appIcon) {
|
|
173
|
+
params.append("app_icon", this.config.appIcon);
|
|
174
|
+
}
|
|
175
|
+
if (this.config.network) {
|
|
176
|
+
params.append("network", this.config.network);
|
|
177
|
+
}
|
|
178
|
+
if (this.config.appDescription) {
|
|
179
|
+
params.append("app_description", this.config.appDescription);
|
|
180
|
+
}
|
|
181
|
+
const scheme = this.config.walletScheme || "column";
|
|
182
|
+
const base = scheme.includes("://") ? scheme : `${scheme}://`;
|
|
183
|
+
return `${base}${base.endsWith("/") ? "" : "/"}?${params.toString()}`;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Utility: Parse the response from Column
|
|
187
|
+
*/
|
|
188
|
+
handleResponse(url) {
|
|
189
|
+
let params;
|
|
190
|
+
try {
|
|
191
|
+
const urlObj = new URL(url.includes("://") ? url : `http://localhost/${url}`);
|
|
192
|
+
const hashStr = urlObj.hash.substring(1);
|
|
193
|
+
const searchStr = urlObj.search.substring(1);
|
|
194
|
+
if (hashStr) {
|
|
195
|
+
params = new URLSearchParams(hashStr);
|
|
196
|
+
} else {
|
|
197
|
+
params = new URLSearchParams(searchStr);
|
|
198
|
+
}
|
|
199
|
+
} catch (e) {
|
|
200
|
+
const hashMatch = url.match(/#(.*)$/);
|
|
201
|
+
const queryMatch = url.match(/\?(.*)$/);
|
|
202
|
+
params = new URLSearchParams(hashMatch ? hashMatch[1] : queryMatch ? queryMatch[1] : url);
|
|
203
|
+
}
|
|
204
|
+
const data = params.get("data");
|
|
205
|
+
const nonce = params.get("nonce");
|
|
206
|
+
const error = params.get("error");
|
|
207
|
+
if (error) {
|
|
208
|
+
throw new Error(`Column Wallet Error: ${error}`);
|
|
209
|
+
}
|
|
210
|
+
if (data && nonce && this.walletEncryptionPublicKey) {
|
|
211
|
+
const decrypted = ColumnCrypto.decryptPayload(
|
|
212
|
+
data,
|
|
213
|
+
nonce,
|
|
214
|
+
this.walletEncryptionPublicKey,
|
|
215
|
+
this.sessionKeyPair.secretKey
|
|
216
|
+
);
|
|
217
|
+
if (!decrypted) {
|
|
218
|
+
throw new Error("Column Wallet Error: Decryption failed. The response may have been tampered with or keys do not match.");
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
...decrypted,
|
|
222
|
+
network: params.get("network")
|
|
223
|
+
// Always include network from URL
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
const response = {};
|
|
227
|
+
params.forEach((value, key) => {
|
|
228
|
+
response[key] = value;
|
|
229
|
+
});
|
|
230
|
+
if (response.column_encryption_public_key) {
|
|
231
|
+
this.walletEncryptionPublicKey = response.column_encryption_public_key;
|
|
232
|
+
}
|
|
233
|
+
return response;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Sets the wallet's public key if known from a previous session
|
|
237
|
+
*/
|
|
238
|
+
setWalletPublicKey(publicKeyB58) {
|
|
239
|
+
this.walletEncryptionPublicKey = publicKeyB58;
|
|
38
240
|
}
|
|
39
241
|
};
|
|
40
242
|
|
|
@@ -173,7 +375,7 @@ var ColumnConnectModal = class {
|
|
|
173
375
|
document.head.appendChild(styleTag);
|
|
174
376
|
}
|
|
175
377
|
open() {
|
|
176
|
-
if (typeof document === "undefined") return;
|
|
378
|
+
if (typeof document === "undefined" || this.overlay) return;
|
|
177
379
|
this.overlay = document.createElement("div");
|
|
178
380
|
this.overlay.className = "column-modal-overlay";
|
|
179
381
|
this.overlay.innerHTML = `
|
|
@@ -220,217 +422,30 @@ var ColumnConnectModal = class {
|
|
|
220
422
|
}
|
|
221
423
|
};
|
|
222
424
|
|
|
223
|
-
// src/
|
|
224
|
-
var
|
|
225
|
-
config;
|
|
226
|
-
sessionKeyPair;
|
|
227
|
-
walletEncryptionPublicKey = null;
|
|
425
|
+
// src/ui/ColumnWalletWeb.ts
|
|
426
|
+
var ColumnWalletWeb = class _ColumnWalletWeb extends ColumnWalletSDK {
|
|
228
427
|
modal;
|
|
229
428
|
constructor(config) {
|
|
230
|
-
|
|
231
|
-
|
|
429
|
+
const detectedConfig = _ColumnWalletWeb.autoDetectMetadata(config);
|
|
430
|
+
super(detectedConfig);
|
|
232
431
|
this.modal = new ColumnConnectModal(() => {
|
|
233
432
|
window.location.href = this.connect();
|
|
234
433
|
});
|
|
235
434
|
}
|
|
236
|
-
autoDetectMetadata(config) {
|
|
435
|
+
static autoDetectMetadata(config) {
|
|
237
436
|
if (typeof document === "undefined") return config;
|
|
238
437
|
const detectedConfig = { ...config };
|
|
239
|
-
if (!detectedConfig.appUrl)
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
if (!detectedConfig.appName) {
|
|
243
|
-
detectedConfig.appName = document.title || "Unknown dApp";
|
|
244
|
-
}
|
|
245
|
-
if (!detectedConfig.appIcon) {
|
|
246
|
-
const iconLink = document.querySelector('link[rel~="icon"]') || document.querySelector('link[rel="apple-touch-icon"]');
|
|
247
|
-
if (iconLink) {
|
|
248
|
-
try {
|
|
249
|
-
detectedConfig.appIcon = new URL(iconLink.getAttribute("href") || "", window.location.origin).href;
|
|
250
|
-
} catch (e) {
|
|
251
|
-
detectedConfig.appIcon = iconLink.href;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
if (!detectedConfig.appDescription) {
|
|
256
|
-
const metaDescription = document.querySelector('meta[name="description"]') || document.querySelector('meta[property="og:description"]');
|
|
257
|
-
if (metaDescription?.content) {
|
|
258
|
-
detectedConfig.appDescription = metaDescription.content;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
if (!detectedConfig.redirectLink) {
|
|
262
|
-
detectedConfig.redirectLink = window.location.href.split("?")[0];
|
|
263
|
-
}
|
|
438
|
+
if (!detectedConfig.appUrl) detectedConfig.appUrl = window.location.origin;
|
|
439
|
+
if (!detectedConfig.appName) detectedConfig.appName = document.title || "Unknown dApp";
|
|
440
|
+
if (!detectedConfig.redirectLink) detectedConfig.redirectLink = window.location.href.split("?")[0];
|
|
264
441
|
return detectedConfig;
|
|
265
442
|
}
|
|
266
|
-
/**
|
|
267
|
-
* Opens the premium Column selection modal
|
|
268
|
-
*/
|
|
269
443
|
openConnectModal() {
|
|
270
444
|
this.modal.open();
|
|
271
445
|
}
|
|
272
|
-
setWalletEncryptionPublicKey(key) {
|
|
273
|
-
this.walletEncryptionPublicKey = key;
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Alias for setWalletEncryptionPublicKey to match docs
|
|
277
|
-
*/
|
|
278
|
-
importWalletKey(key) {
|
|
279
|
-
this.setWalletEncryptionPublicKey(key);
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Step 1: Connect to the wallet
|
|
283
|
-
*/
|
|
284
|
-
connect() {
|
|
285
|
-
const params = new URLSearchParams({
|
|
286
|
-
request: "connect",
|
|
287
|
-
app_url: this.config.appUrl || "",
|
|
288
|
-
app_name: this.config.appName || "",
|
|
289
|
-
dapp_encryption_public_key: bs582.encode(this.sessionKeyPair.publicKey),
|
|
290
|
-
redirect_link: this.config.redirectLink || ""
|
|
291
|
-
});
|
|
292
|
-
if (this.config.appIcon) {
|
|
293
|
-
params.append("app_icon", this.config.appIcon);
|
|
294
|
-
}
|
|
295
|
-
if (this.config.network) {
|
|
296
|
-
params.append("network", this.config.network);
|
|
297
|
-
}
|
|
298
|
-
if (this.config.appDescription) {
|
|
299
|
-
params.append("app_description", this.config.appDescription);
|
|
300
|
-
}
|
|
301
|
-
const scheme = this.config.walletScheme || "column";
|
|
302
|
-
const base = scheme.includes("://") ? scheme : `${scheme}://`;
|
|
303
|
-
return `${base}${base.endsWith("/") ? "" : "/"}?${params.toString()}`;
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Step 2: Sign and Submit a transaction
|
|
307
|
-
*/
|
|
308
|
-
signAndSubmitTransaction(transaction) {
|
|
309
|
-
if (!this.walletEncryptionPublicKey) {
|
|
310
|
-
throw new Error("Wallet not connected. Call connect() first and store the wallet_encryption_public_key.");
|
|
311
|
-
}
|
|
312
|
-
const payload = {
|
|
313
|
-
transaction
|
|
314
|
-
};
|
|
315
|
-
const encrypted = ColumnCrypto.encryptPayload(
|
|
316
|
-
payload,
|
|
317
|
-
this.walletEncryptionPublicKey,
|
|
318
|
-
this.sessionKeyPair.secretKey
|
|
319
|
-
);
|
|
320
|
-
const params = new URLSearchParams({
|
|
321
|
-
request: "signAndSubmitTransaction",
|
|
322
|
-
app_url: this.config.appUrl || "",
|
|
323
|
-
app_name: this.config.appName || "",
|
|
324
|
-
dapp_encryption_public_key: bs582.encode(this.sessionKeyPair.publicKey),
|
|
325
|
-
data: encrypted.data,
|
|
326
|
-
nonce: encrypted.nonce,
|
|
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 3: Sign a simple message
|
|
344
|
-
*/
|
|
345
|
-
signMessage(message) {
|
|
346
|
-
if (!this.walletEncryptionPublicKey) {
|
|
347
|
-
throw new Error("Wallet not connected.");
|
|
348
|
-
}
|
|
349
|
-
const payload = {
|
|
350
|
-
message
|
|
351
|
-
};
|
|
352
|
-
const encrypted = ColumnCrypto.encryptPayload(
|
|
353
|
-
payload,
|
|
354
|
-
this.walletEncryptionPublicKey,
|
|
355
|
-
this.sessionKeyPair.secretKey
|
|
356
|
-
);
|
|
357
|
-
const params = new URLSearchParams({
|
|
358
|
-
request: "signMessage",
|
|
359
|
-
app_url: this.config.appUrl || "",
|
|
360
|
-
app_name: this.config.appName || "",
|
|
361
|
-
dapp_encryption_public_key: bs582.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
|
-
* Utility: Parse the response from Column
|
|
381
|
-
*/
|
|
382
|
-
handleResponse(url) {
|
|
383
|
-
let params;
|
|
384
|
-
try {
|
|
385
|
-
const urlObj = new URL(url.includes("://") ? url : `http://localhost/${url}`);
|
|
386
|
-
const hashStr = urlObj.hash.substring(1);
|
|
387
|
-
const searchStr = urlObj.search.substring(1);
|
|
388
|
-
if (hashStr) {
|
|
389
|
-
params = new URLSearchParams(hashStr);
|
|
390
|
-
} else {
|
|
391
|
-
params = new URLSearchParams(searchStr);
|
|
392
|
-
}
|
|
393
|
-
} catch (e) {
|
|
394
|
-
const hashMatch = url.match(/#(.*)$/);
|
|
395
|
-
const queryMatch = url.match(/\?(.*)$/);
|
|
396
|
-
params = new URLSearchParams(hashMatch ? hashMatch[1] : queryMatch ? queryMatch[1] : url);
|
|
397
|
-
}
|
|
398
|
-
const data = params.get("data");
|
|
399
|
-
const nonce = params.get("nonce");
|
|
400
|
-
const error = params.get("error");
|
|
401
|
-
if (error) {
|
|
402
|
-
throw new Error(`Column Wallet Error: ${error}`);
|
|
403
|
-
}
|
|
404
|
-
if (data && nonce && this.walletEncryptionPublicKey) {
|
|
405
|
-
const decrypted = ColumnCrypto.decryptPayload(
|
|
406
|
-
data,
|
|
407
|
-
nonce,
|
|
408
|
-
this.walletEncryptionPublicKey,
|
|
409
|
-
this.sessionKeyPair.secretKey
|
|
410
|
-
);
|
|
411
|
-
return {
|
|
412
|
-
...decrypted,
|
|
413
|
-
network: params.get("network")
|
|
414
|
-
// Always include network from URL
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
const response = {};
|
|
418
|
-
params.forEach((value, key) => {
|
|
419
|
-
response[key] = value;
|
|
420
|
-
});
|
|
421
|
-
if (response.column_encryption_public_key) {
|
|
422
|
-
this.walletEncryptionPublicKey = response.column_encryption_public_key;
|
|
423
|
-
}
|
|
424
|
-
return response;
|
|
425
|
-
}
|
|
426
|
-
/**
|
|
427
|
-
* Sets the wallet's public key if known from a previous session
|
|
428
|
-
*/
|
|
429
|
-
setWalletPublicKey(publicKeyB58) {
|
|
430
|
-
this.walletEncryptionPublicKey = publicKeyB58;
|
|
431
|
-
}
|
|
432
446
|
};
|
|
433
447
|
export {
|
|
434
448
|
ColumnCrypto,
|
|
435
|
-
ColumnWalletSDK
|
|
449
|
+
ColumnWalletSDK,
|
|
450
|
+
ColumnWalletWeb
|
|
436
451
|
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@column-org/wallet-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Column Wallet Mobile Deep-Link SDK for Movement/Aptos ecosystem",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
|
+
"react-native": "src/index.native.ts",
|
|
7
8
|
"types": "dist/index.d.ts",
|
|
8
9
|
"files": [
|
|
9
|
-
"dist"
|
|
10
|
+
"dist",
|
|
11
|
+
"src"
|
|
10
12
|
],
|
|
11
13
|
"publishConfig": {
|
|
12
14
|
"access": "public"
|
|
@@ -30,6 +32,7 @@
|
|
|
30
32
|
"dependencies": {
|
|
31
33
|
"bs58": "^6.0.0",
|
|
32
34
|
"buffer": "^6.0.3",
|
|
35
|
+
"react-native-get-random-values": "^1.11.0",
|
|
33
36
|
"tweetnacl": "^1.0.3"
|
|
34
37
|
},
|
|
35
38
|
"devDependencies": {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as nacl from 'tweetnacl'
|
|
2
|
+
import bs58 from 'bs58'
|
|
3
|
+
import { Buffer } from 'buffer'
|
|
4
|
+
|
|
5
|
+
export interface ColumnSDKConfig {
|
|
6
|
+
appUrl?: string
|
|
7
|
+
appName?: string
|
|
8
|
+
redirectLink?: string
|
|
9
|
+
appIcon?: string
|
|
10
|
+
appDescription?: string
|
|
11
|
+
walletScheme?: string
|
|
12
|
+
network?: string
|
|
13
|
+
sessionSecretKey?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class ColumnCrypto {
|
|
17
|
+
static generateKeyPair(): nacl.BoxKeyPair {
|
|
18
|
+
return nacl.box.keyPair()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static encryptPayload(
|
|
22
|
+
payload: any,
|
|
23
|
+
targetPublicKeyB58: string,
|
|
24
|
+
mySecretKey: Uint8Array
|
|
25
|
+
): { data: string; nonce: string } {
|
|
26
|
+
const sharedSecret = nacl.box.before(
|
|
27
|
+
bs58.decode(targetPublicKeyB58),
|
|
28
|
+
mySecretKey
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const nonce = nacl.randomBytes(nacl.box.nonceLength)
|
|
32
|
+
const message = Buffer.from(JSON.stringify(payload), 'utf8')
|
|
33
|
+
|
|
34
|
+
const encrypted = nacl.box.after(message, nonce, sharedSecret)
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
data: bs58.encode(encrypted),
|
|
38
|
+
nonce: bs58.encode(nonce)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static decryptPayload(
|
|
43
|
+
encryptedDataB58: string,
|
|
44
|
+
nonceB58: string,
|
|
45
|
+
sourcePublicKeyB58: string,
|
|
46
|
+
mySecretKey: Uint8Array
|
|
47
|
+
): any {
|
|
48
|
+
const sharedSecret = nacl.box.before(
|
|
49
|
+
bs58.decode(sourcePublicKeyB58),
|
|
50
|
+
mySecretKey
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
const decrypted = nacl.box.open.after(
|
|
54
|
+
bs58.decode(encryptedDataB58),
|
|
55
|
+
bs58.decode(nonceB58),
|
|
56
|
+
sharedSecret
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
if (!decrypted) return null
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const jsonString = Buffer.from(decrypted).toString('utf8')
|
|
63
|
+
return JSON.parse(jsonString)
|
|
64
|
+
} catch (e) {
|
|
65
|
+
console.error('ColumnCrypto: Failed to parse decrypted payload', e)
|
|
66
|
+
return null
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|