phantasma-sdk-ts 0.5.2 → 0.7.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.
- package/dist/cjs/core/link/easyConnect.js +20 -2
- package/dist/cjs/core/link/phantasmaLink.js +124 -14
- package/dist/esm/core/link/easyConnect.js +20 -2
- package/dist/esm/core/link/phantasmaLink.js +125 -15
- package/dist/types/core/link/easyConnect.d.ts +3 -1
- package/dist/types/core/link/easyConnect.d.ts.map +1 -1
- package/dist/types/core/link/phantasmaLink.d.ts +12 -1
- package/dist/types/core/link/phantasmaLink.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -13,8 +13,7 @@ class EasyConnect {
|
|
|
13
13
|
this.link = new phantasmaLink_js_1.PhantasmaLink('easyConnect', false);
|
|
14
14
|
this.connected = false;
|
|
15
15
|
this.requiredVersion = 4;
|
|
16
|
-
|
|
17
|
-
this.nexus = easyScript_js_1.Nexus.Mainnet;
|
|
16
|
+
this.nexus = null;
|
|
18
17
|
if (_options == null) {
|
|
19
18
|
this.setConfig('auto');
|
|
20
19
|
}
|
|
@@ -59,6 +58,12 @@ class EasyConnect {
|
|
|
59
58
|
//Console Logging for Debugging Purposes
|
|
60
59
|
if (data) {
|
|
61
60
|
that.connected = true;
|
|
61
|
+
that.nexus =
|
|
62
|
+
that.link.nexus === easyScript_js_1.Nexus.Mainnet ||
|
|
63
|
+
that.link.nexus === easyScript_js_1.Nexus.Simnet ||
|
|
64
|
+
that.link.nexus === easyScript_js_1.Nexus.Testnet
|
|
65
|
+
? that.link.nexus
|
|
66
|
+
: null;
|
|
62
67
|
onSuccess(data);
|
|
63
68
|
logger_js_1.logger.log('%c[EasyConnect Connected]', 'color:green');
|
|
64
69
|
logger_js_1.logger.log("Wallet Address '" + that.link.account.address + "' connected via " + that.link.wallet);
|
|
@@ -72,6 +77,7 @@ class EasyConnect {
|
|
|
72
77
|
disconnect(_message = 'Graceful Disconect') {
|
|
73
78
|
this.link.disconnect(_message);
|
|
74
79
|
this.connected = false;
|
|
80
|
+
this.nexus = null;
|
|
75
81
|
}
|
|
76
82
|
async query(_type = null, _arguments = null, _callback = (data) => {
|
|
77
83
|
logger_js_1.logger.log(data);
|
|
@@ -160,6 +166,18 @@ class EasyConnect {
|
|
|
160
166
|
onFail(message);
|
|
161
167
|
}
|
|
162
168
|
}
|
|
169
|
+
signPrebuiltTransaction(tx, onSuccess = (data) => { }, onFail = (data) => {
|
|
170
|
+
logger_js_1.logger.log('%cError: ' + data, 'color:red');
|
|
171
|
+
}) {
|
|
172
|
+
if (this.connected == true) {
|
|
173
|
+
this.link.signPrebuiltTransaction(tx, onSuccess, onFail);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
const message = 'Wallet is not connected';
|
|
177
|
+
logger_js_1.logger.log('%c' + message, 'color:red');
|
|
178
|
+
onFail(message);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
163
181
|
invokeScript(script, _callback) {
|
|
164
182
|
this.link.invokeScript(script, _callback);
|
|
165
183
|
}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PhantasmaLink = void 0;
|
|
4
|
+
const Transaction_js_1 = require("../tx/Transaction.js");
|
|
4
5
|
const index_js_1 = require("../vm/index.js");
|
|
5
6
|
const ProofOfWork_js_1 = require("./interfaces/ProofOfWork.js");
|
|
6
7
|
const CarbonBlob_js_1 = require("../types/Carbon/CarbonBlob.js");
|
|
7
8
|
const Hex_js_1 = require("../utils/Hex.js");
|
|
9
|
+
const index_js_2 = require("../types/index.js");
|
|
8
10
|
const logger_js_1 = require("../utils/logger.js");
|
|
9
11
|
class PhantasmaLink {
|
|
10
12
|
//Construct The Link
|
|
11
13
|
constructor(dappID, logging = true) {
|
|
12
14
|
this.lastSocketErrorMessage = null;
|
|
15
|
+
this.socketTransport = null;
|
|
16
|
+
this.socketOpen = false;
|
|
13
17
|
this.requestID = 0;
|
|
14
18
|
//Message Logging
|
|
15
19
|
this.onMessage = (msg) => {
|
|
@@ -18,7 +22,7 @@ class PhantasmaLink {
|
|
|
18
22
|
}
|
|
19
23
|
};
|
|
20
24
|
this.version = 4;
|
|
21
|
-
this.nexus = '
|
|
25
|
+
this.nexus = '';
|
|
22
26
|
this.chain = 'main';
|
|
23
27
|
this.platform = 'poltergeist';
|
|
24
28
|
//Turn On|Off Console Logging
|
|
@@ -36,6 +40,19 @@ class PhantasmaLink {
|
|
|
36
40
|
this.onLogin = function (succ) { }; //Does Nothing for Now
|
|
37
41
|
this.onError = function (message) { }; //Does Nothing for Now
|
|
38
42
|
}
|
|
43
|
+
// Preserve wallet-side failure details whenever the transport provides them.
|
|
44
|
+
describeFailure(result, fallback) {
|
|
45
|
+
if (typeof result === 'string' && result.length > 0) {
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
if (result && typeof result.error === 'string' && result.error.length > 0) {
|
|
49
|
+
return result.error;
|
|
50
|
+
}
|
|
51
|
+
if (result && typeof result.message === 'string' && result.message.length > 0) {
|
|
52
|
+
return result.message;
|
|
53
|
+
}
|
|
54
|
+
return fallback;
|
|
55
|
+
}
|
|
39
56
|
//Connect To Wallet
|
|
40
57
|
login(onLoginCallback, onErrorCallback, version = 4, platform = 'phantasma', providerHint = 'poltergeist') {
|
|
41
58
|
this.providerHint = providerHint;
|
|
@@ -189,19 +206,26 @@ class PhantasmaLink {
|
|
|
189
206
|
signTxSignature(tx, callback, onErrorCallback, signature = 'Ed25519') {
|
|
190
207
|
if (!this.socket) {
|
|
191
208
|
this.onMessage('not logged in');
|
|
209
|
+
if (onErrorCallback) {
|
|
210
|
+
onErrorCallback('Wallet is not connected');
|
|
211
|
+
}
|
|
192
212
|
return;
|
|
193
213
|
}
|
|
194
214
|
if (tx == null) {
|
|
195
215
|
this.onMessage('invalid data, sorry :(');
|
|
216
|
+
if (onErrorCallback) {
|
|
217
|
+
onErrorCallback('Invalid transaction data');
|
|
218
|
+
}
|
|
196
219
|
return;
|
|
197
220
|
}
|
|
198
|
-
if (tx.length >=
|
|
221
|
+
if (tx.length >= 65536) {
|
|
199
222
|
this.onMessage('data too big, sorry :(');
|
|
200
223
|
if (onErrorCallback) {
|
|
201
|
-
onErrorCallback();
|
|
224
|
+
onErrorCallback('Transaction data is too big');
|
|
202
225
|
}
|
|
203
226
|
return;
|
|
204
227
|
}
|
|
228
|
+
this.onError = onErrorCallback;
|
|
205
229
|
let signDataStr = 'signTxSignature/' + tx + '/' + signature + '/' + this.platform;
|
|
206
230
|
var that = this; //Allows the use of 'this' inside sendLinkRequest Object
|
|
207
231
|
this.sendLinkRequest(signDataStr, function (result) {
|
|
@@ -213,11 +237,78 @@ class PhantasmaLink {
|
|
|
213
237
|
}
|
|
214
238
|
else {
|
|
215
239
|
if (onErrorCallback) {
|
|
216
|
-
onErrorCallback();
|
|
240
|
+
onErrorCallback(that.describeFailure(result, 'Wallet rejected transaction signature'));
|
|
217
241
|
}
|
|
218
242
|
}
|
|
219
243
|
});
|
|
220
244
|
}
|
|
245
|
+
decodeWalletSignatureBytes(signatureHex, signature) {
|
|
246
|
+
if (signature !== 'Ed25519') {
|
|
247
|
+
throw new Error(`Unsupported transaction signature type: ${signature}`);
|
|
248
|
+
}
|
|
249
|
+
const reader = new index_js_2.PBinaryReader((0, Hex_js_1.hexToBytes)(signatureHex));
|
|
250
|
+
const rawSignatureHex = reader.readByteArray();
|
|
251
|
+
if (typeof rawSignatureHex !== 'string' || rawSignatureHex.length === 0) {
|
|
252
|
+
throw new Error('Wallet returned an empty transaction signature');
|
|
253
|
+
}
|
|
254
|
+
return (0, Hex_js_1.hexToBytes)(rawSignatureHex);
|
|
255
|
+
}
|
|
256
|
+
signPrebuiltTransaction(tx, callback, onErrorCallback, signature = 'Ed25519') {
|
|
257
|
+
if (!tx) {
|
|
258
|
+
const message = 'Error: Invalid transaction';
|
|
259
|
+
this.onMessage(message);
|
|
260
|
+
if (onErrorCallback) {
|
|
261
|
+
onErrorCallback(message);
|
|
262
|
+
}
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
let unsignedTxHex;
|
|
266
|
+
try {
|
|
267
|
+
unsignedTxHex = tx.ToStringEncoded(false).toUpperCase();
|
|
268
|
+
}
|
|
269
|
+
catch (err) {
|
|
270
|
+
const message = 'Error: Unable to encode unsigned transaction';
|
|
271
|
+
this.onMessage(message + (err?.message ? ` (${err.message})` : ''));
|
|
272
|
+
if (onErrorCallback) {
|
|
273
|
+
onErrorCallback(message);
|
|
274
|
+
}
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
this.signTxSignature(unsignedTxHex, (result) => {
|
|
278
|
+
if (!result?.success || typeof result.signature !== 'string' || result.signature.length === 0) {
|
|
279
|
+
const failure = this.describeFailure(result, 'Wallet rejected transaction signature');
|
|
280
|
+
if (onErrorCallback) {
|
|
281
|
+
onErrorCallback(failure);
|
|
282
|
+
}
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
try {
|
|
286
|
+
const signedTx = Transaction_js_1.Transaction.FromBytes(unsignedTxHex);
|
|
287
|
+
signedTx.signatures = [
|
|
288
|
+
new index_js_2.Ed25519Signature(this.decodeWalletSignatureBytes(result.signature, signature)),
|
|
289
|
+
];
|
|
290
|
+
if (this.account?.address && !signedTx.VerifySignature(this.account.address)) {
|
|
291
|
+
throw new Error('Wallet returned a signature that does not match the connected account');
|
|
292
|
+
}
|
|
293
|
+
callback({
|
|
294
|
+
success: true,
|
|
295
|
+
signature: result.signature,
|
|
296
|
+
signedTx: signedTx.ToStringEncoded(true).toUpperCase(),
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
catch (err) {
|
|
300
|
+
const message = err?.message || 'Unable to assemble signed transaction';
|
|
301
|
+
if (onErrorCallback) {
|
|
302
|
+
onErrorCallback(message);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}, (message) => {
|
|
306
|
+
const failure = message || this.lastSocketErrorMessage || 'Wallet rejected transaction signature';
|
|
307
|
+
if (onErrorCallback) {
|
|
308
|
+
onErrorCallback(failure);
|
|
309
|
+
}
|
|
310
|
+
}, signature);
|
|
311
|
+
}
|
|
221
312
|
multiSig(subject, callback, onErrorCallback, signature = 'Ed25519') {
|
|
222
313
|
if (!this.socket) {
|
|
223
314
|
this.onMessage('not logged in');
|
|
@@ -292,6 +383,9 @@ class PhantasmaLink {
|
|
|
292
383
|
//Sends Signiture Request To Connected Wallet For Script
|
|
293
384
|
this.sendLinkRequest('getNexus/', function (result) {
|
|
294
385
|
if (result.success) {
|
|
386
|
+
if (typeof result.nexus === 'string') {
|
|
387
|
+
that.nexus = result.nexus;
|
|
388
|
+
}
|
|
295
389
|
that.onMessage('Nexus Query,: ' + result);
|
|
296
390
|
if (callback) {
|
|
297
391
|
callback(result);
|
|
@@ -363,22 +457,31 @@ class PhantasmaLink {
|
|
|
363
457
|
if (this.socket) {
|
|
364
458
|
this.socket.close();
|
|
365
459
|
}
|
|
460
|
+
const useInjectedSocket =
|
|
461
|
+
// @ts-ignore
|
|
462
|
+
!!window.PhantasmaLinkSocket && this.providerHint !== 'poltergeist';
|
|
463
|
+
this.socketTransport = useInjectedSocket ? 'injected' : 'websocket';
|
|
464
|
+
this.socketOpen = false;
|
|
465
|
+
this.onMessage(useInjectedSocket
|
|
466
|
+
? 'Using injected PhantasmaLinkSocket transport'
|
|
467
|
+
: `Using raw WebSocket transport: ${path}`);
|
|
366
468
|
//@ts-ignore
|
|
367
|
-
this.socket =
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
: new WebSocket(path);
|
|
469
|
+
this.socket = useInjectedSocket
|
|
470
|
+
? // @ts-ignore
|
|
471
|
+
new PhantasmaLinkSocket()
|
|
472
|
+
: new WebSocket(path);
|
|
372
473
|
this.requestCallback = null;
|
|
373
474
|
this.lastSocketErrorMessage = null;
|
|
374
475
|
this.token = null;
|
|
375
476
|
this.account = null;
|
|
477
|
+
this.nexus = '';
|
|
376
478
|
this.requestID = 0;
|
|
377
479
|
let authorizeRequest = 'authorize/' + this.dapp + '/' + this.version;
|
|
378
480
|
let getAccountRequest = 'getAccount/' + this.platform;
|
|
379
481
|
let that = this;
|
|
380
482
|
//Once Socket Opened
|
|
381
483
|
this.socket.onopen = function (e) {
|
|
484
|
+
that.socketOpen = true;
|
|
382
485
|
that.onMessage('Connection established, authorizing dapp in wallet...');
|
|
383
486
|
if (isResume) {
|
|
384
487
|
that.fetchWallet(undefined, undefined);
|
|
@@ -389,6 +492,7 @@ class PhantasmaLink {
|
|
|
389
492
|
if (result.success) {
|
|
390
493
|
that.token = result.token;
|
|
391
494
|
that.wallet = result.wallet;
|
|
495
|
+
that.nexus = typeof result.nexus === 'string' ? result.nexus : '';
|
|
392
496
|
that.onMessage('Authorized, obtaining account info...');
|
|
393
497
|
that.sendLinkRequest(getAccountRequest, function (result) {
|
|
394
498
|
if (result.success) {
|
|
@@ -405,7 +509,7 @@ class PhantasmaLink {
|
|
|
405
509
|
});
|
|
406
510
|
}
|
|
407
511
|
else {
|
|
408
|
-
that.onError('Authorization failed...');
|
|
512
|
+
that.onError(that.describeFailure(result, 'Authorization failed...'));
|
|
409
513
|
that.disconnect('Auth Failure');
|
|
410
514
|
}
|
|
411
515
|
});
|
|
@@ -428,8 +532,9 @@ class PhantasmaLink {
|
|
|
428
532
|
that.onError('Could not obtain account info... Make sure you have an account currently logged in');
|
|
429
533
|
that.disconnect(true);
|
|
430
534
|
break;
|
|
431
|
-
case 'A previouus request is still pending'
|
|
432
|
-
|
|
535
|
+
case 'A previouus request is still pending':
|
|
536
|
+
case 'A previous request is still pending':
|
|
537
|
+
that.onError(that.describeFailure(obj, 'You have a pending action in your wallet'));
|
|
433
538
|
break;
|
|
434
539
|
case 'user rejected':
|
|
435
540
|
that.onError('Transaction cancelled by user in ' + that.wallet);
|
|
@@ -455,6 +560,7 @@ class PhantasmaLink {
|
|
|
455
560
|
};
|
|
456
561
|
//Cleanup After Socket Closes
|
|
457
562
|
this.socket.onclose = function (event) {
|
|
563
|
+
that.socketOpen = false;
|
|
458
564
|
const reason = event.reason && event.reason.length > 0
|
|
459
565
|
? event.reason
|
|
460
566
|
: that.lastSocketErrorMessage || (event.wasClean ? 'Wallet connection closed' : 'Connection terminated unexpectedly');
|
|
@@ -505,8 +611,11 @@ class PhantasmaLink {
|
|
|
505
611
|
this.requestCallback = callback;
|
|
506
612
|
const socket = this.socket;
|
|
507
613
|
const openState = typeof WebSocket !== 'undefined' && typeof WebSocket.OPEN === 'number' ? WebSocket.OPEN : 1;
|
|
508
|
-
const
|
|
509
|
-
|
|
614
|
+
const hasSend = socket && typeof socket.send === 'function';
|
|
615
|
+
const hasReadyState = socket && typeof socket.readyState === 'number';
|
|
616
|
+
const isSocketOpen = hasSend &&
|
|
617
|
+
(hasReadyState ? socket.readyState === openState : this.socketOpen);
|
|
618
|
+
if (!socket || !hasSend || !isSocketOpen) {
|
|
510
619
|
this.handleSocketFailure('Wallet connection is closed. Please reconnect to your wallet.');
|
|
511
620
|
return;
|
|
512
621
|
}
|
|
@@ -540,6 +649,7 @@ class PhantasmaLink {
|
|
|
540
649
|
//Disconnect The Wallet Connection Socket
|
|
541
650
|
disconnect(triggered) {
|
|
542
651
|
this.onMessage('Disconnecting Phantasma Link: ' + triggered);
|
|
652
|
+
this.socketOpen = false;
|
|
543
653
|
if (this.socket)
|
|
544
654
|
this.socket.close();
|
|
545
655
|
}
|
|
@@ -10,8 +10,7 @@ export class EasyConnect {
|
|
|
10
10
|
this.link = new PhantasmaLink('easyConnect', false);
|
|
11
11
|
this.connected = false;
|
|
12
12
|
this.requiredVersion = 4;
|
|
13
|
-
|
|
14
|
-
this.nexus = Nexus.Mainnet;
|
|
13
|
+
this.nexus = null;
|
|
15
14
|
if (_options == null) {
|
|
16
15
|
this.setConfig('auto');
|
|
17
16
|
}
|
|
@@ -56,6 +55,12 @@ export class EasyConnect {
|
|
|
56
55
|
//Console Logging for Debugging Purposes
|
|
57
56
|
if (data) {
|
|
58
57
|
that.connected = true;
|
|
58
|
+
that.nexus =
|
|
59
|
+
that.link.nexus === Nexus.Mainnet ||
|
|
60
|
+
that.link.nexus === Nexus.Simnet ||
|
|
61
|
+
that.link.nexus === Nexus.Testnet
|
|
62
|
+
? that.link.nexus
|
|
63
|
+
: null;
|
|
59
64
|
onSuccess(data);
|
|
60
65
|
logger.log('%c[EasyConnect Connected]', 'color:green');
|
|
61
66
|
logger.log("Wallet Address '" + that.link.account.address + "' connected via " + that.link.wallet);
|
|
@@ -69,6 +74,7 @@ export class EasyConnect {
|
|
|
69
74
|
disconnect(_message = 'Graceful Disconect') {
|
|
70
75
|
this.link.disconnect(_message);
|
|
71
76
|
this.connected = false;
|
|
77
|
+
this.nexus = null;
|
|
72
78
|
}
|
|
73
79
|
async query(_type = null, _arguments = null, _callback = (data) => {
|
|
74
80
|
logger.log(data);
|
|
@@ -157,6 +163,18 @@ export class EasyConnect {
|
|
|
157
163
|
onFail(message);
|
|
158
164
|
}
|
|
159
165
|
}
|
|
166
|
+
signPrebuiltTransaction(tx, onSuccess = (data) => { }, onFail = (data) => {
|
|
167
|
+
logger.log('%cError: ' + data, 'color:red');
|
|
168
|
+
}) {
|
|
169
|
+
if (this.connected == true) {
|
|
170
|
+
this.link.signPrebuiltTransaction(tx, onSuccess, onFail);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
const message = 'Wallet is not connected';
|
|
174
|
+
logger.log('%c' + message, 'color:red');
|
|
175
|
+
onFail(message);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
160
178
|
invokeScript(script, _callback) {
|
|
161
179
|
this.link.invokeScript(script, _callback);
|
|
162
180
|
}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import { Transaction } from '../tx/Transaction.js';
|
|
1
2
|
import { ScriptBuilder } from '../vm/index.js';
|
|
2
3
|
import { ProofOfWork } from './interfaces/ProofOfWork.js';
|
|
3
4
|
import { CarbonBlob } from '../types/Carbon/CarbonBlob.js';
|
|
4
|
-
import { bytesToHex } from '../utils/Hex.js';
|
|
5
|
+
import { bytesToHex, hexToBytes } from '../utils/Hex.js';
|
|
6
|
+
import { Ed25519Signature, PBinaryReader } from '../types/index.js';
|
|
5
7
|
import { logger } from '../utils/logger.js';
|
|
6
8
|
export class PhantasmaLink {
|
|
7
9
|
//Construct The Link
|
|
8
10
|
constructor(dappID, logging = true) {
|
|
9
11
|
this.lastSocketErrorMessage = null;
|
|
12
|
+
this.socketTransport = null;
|
|
13
|
+
this.socketOpen = false;
|
|
10
14
|
this.requestID = 0;
|
|
11
15
|
//Message Logging
|
|
12
16
|
this.onMessage = (msg) => {
|
|
@@ -15,7 +19,7 @@ export class PhantasmaLink {
|
|
|
15
19
|
}
|
|
16
20
|
};
|
|
17
21
|
this.version = 4;
|
|
18
|
-
this.nexus = '
|
|
22
|
+
this.nexus = '';
|
|
19
23
|
this.chain = 'main';
|
|
20
24
|
this.platform = 'poltergeist';
|
|
21
25
|
//Turn On|Off Console Logging
|
|
@@ -33,6 +37,19 @@ export class PhantasmaLink {
|
|
|
33
37
|
this.onLogin = function (succ) { }; //Does Nothing for Now
|
|
34
38
|
this.onError = function (message) { }; //Does Nothing for Now
|
|
35
39
|
}
|
|
40
|
+
// Preserve wallet-side failure details whenever the transport provides them.
|
|
41
|
+
describeFailure(result, fallback) {
|
|
42
|
+
if (typeof result === 'string' && result.length > 0) {
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
if (result && typeof result.error === 'string' && result.error.length > 0) {
|
|
46
|
+
return result.error;
|
|
47
|
+
}
|
|
48
|
+
if (result && typeof result.message === 'string' && result.message.length > 0) {
|
|
49
|
+
return result.message;
|
|
50
|
+
}
|
|
51
|
+
return fallback;
|
|
52
|
+
}
|
|
36
53
|
//Connect To Wallet
|
|
37
54
|
login(onLoginCallback, onErrorCallback, version = 4, platform = 'phantasma', providerHint = 'poltergeist') {
|
|
38
55
|
this.providerHint = providerHint;
|
|
@@ -186,19 +203,26 @@ export class PhantasmaLink {
|
|
|
186
203
|
signTxSignature(tx, callback, onErrorCallback, signature = 'Ed25519') {
|
|
187
204
|
if (!this.socket) {
|
|
188
205
|
this.onMessage('not logged in');
|
|
206
|
+
if (onErrorCallback) {
|
|
207
|
+
onErrorCallback('Wallet is not connected');
|
|
208
|
+
}
|
|
189
209
|
return;
|
|
190
210
|
}
|
|
191
211
|
if (tx == null) {
|
|
192
212
|
this.onMessage('invalid data, sorry :(');
|
|
213
|
+
if (onErrorCallback) {
|
|
214
|
+
onErrorCallback('Invalid transaction data');
|
|
215
|
+
}
|
|
193
216
|
return;
|
|
194
217
|
}
|
|
195
|
-
if (tx.length >=
|
|
218
|
+
if (tx.length >= 65536) {
|
|
196
219
|
this.onMessage('data too big, sorry :(');
|
|
197
220
|
if (onErrorCallback) {
|
|
198
|
-
onErrorCallback();
|
|
221
|
+
onErrorCallback('Transaction data is too big');
|
|
199
222
|
}
|
|
200
223
|
return;
|
|
201
224
|
}
|
|
225
|
+
this.onError = onErrorCallback;
|
|
202
226
|
let signDataStr = 'signTxSignature/' + tx + '/' + signature + '/' + this.platform;
|
|
203
227
|
var that = this; //Allows the use of 'this' inside sendLinkRequest Object
|
|
204
228
|
this.sendLinkRequest(signDataStr, function (result) {
|
|
@@ -210,11 +234,78 @@ export class PhantasmaLink {
|
|
|
210
234
|
}
|
|
211
235
|
else {
|
|
212
236
|
if (onErrorCallback) {
|
|
213
|
-
onErrorCallback();
|
|
237
|
+
onErrorCallback(that.describeFailure(result, 'Wallet rejected transaction signature'));
|
|
214
238
|
}
|
|
215
239
|
}
|
|
216
240
|
});
|
|
217
241
|
}
|
|
242
|
+
decodeWalletSignatureBytes(signatureHex, signature) {
|
|
243
|
+
if (signature !== 'Ed25519') {
|
|
244
|
+
throw new Error(`Unsupported transaction signature type: ${signature}`);
|
|
245
|
+
}
|
|
246
|
+
const reader = new PBinaryReader(hexToBytes(signatureHex));
|
|
247
|
+
const rawSignatureHex = reader.readByteArray();
|
|
248
|
+
if (typeof rawSignatureHex !== 'string' || rawSignatureHex.length === 0) {
|
|
249
|
+
throw new Error('Wallet returned an empty transaction signature');
|
|
250
|
+
}
|
|
251
|
+
return hexToBytes(rawSignatureHex);
|
|
252
|
+
}
|
|
253
|
+
signPrebuiltTransaction(tx, callback, onErrorCallback, signature = 'Ed25519') {
|
|
254
|
+
if (!tx) {
|
|
255
|
+
const message = 'Error: Invalid transaction';
|
|
256
|
+
this.onMessage(message);
|
|
257
|
+
if (onErrorCallback) {
|
|
258
|
+
onErrorCallback(message);
|
|
259
|
+
}
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
let unsignedTxHex;
|
|
263
|
+
try {
|
|
264
|
+
unsignedTxHex = tx.ToStringEncoded(false).toUpperCase();
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
const message = 'Error: Unable to encode unsigned transaction';
|
|
268
|
+
this.onMessage(message + (err?.message ? ` (${err.message})` : ''));
|
|
269
|
+
if (onErrorCallback) {
|
|
270
|
+
onErrorCallback(message);
|
|
271
|
+
}
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
this.signTxSignature(unsignedTxHex, (result) => {
|
|
275
|
+
if (!result?.success || typeof result.signature !== 'string' || result.signature.length === 0) {
|
|
276
|
+
const failure = this.describeFailure(result, 'Wallet rejected transaction signature');
|
|
277
|
+
if (onErrorCallback) {
|
|
278
|
+
onErrorCallback(failure);
|
|
279
|
+
}
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
try {
|
|
283
|
+
const signedTx = Transaction.FromBytes(unsignedTxHex);
|
|
284
|
+
signedTx.signatures = [
|
|
285
|
+
new Ed25519Signature(this.decodeWalletSignatureBytes(result.signature, signature)),
|
|
286
|
+
];
|
|
287
|
+
if (this.account?.address && !signedTx.VerifySignature(this.account.address)) {
|
|
288
|
+
throw new Error('Wallet returned a signature that does not match the connected account');
|
|
289
|
+
}
|
|
290
|
+
callback({
|
|
291
|
+
success: true,
|
|
292
|
+
signature: result.signature,
|
|
293
|
+
signedTx: signedTx.ToStringEncoded(true).toUpperCase(),
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
const message = err?.message || 'Unable to assemble signed transaction';
|
|
298
|
+
if (onErrorCallback) {
|
|
299
|
+
onErrorCallback(message);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}, (message) => {
|
|
303
|
+
const failure = message || this.lastSocketErrorMessage || 'Wallet rejected transaction signature';
|
|
304
|
+
if (onErrorCallback) {
|
|
305
|
+
onErrorCallback(failure);
|
|
306
|
+
}
|
|
307
|
+
}, signature);
|
|
308
|
+
}
|
|
218
309
|
multiSig(subject, callback, onErrorCallback, signature = 'Ed25519') {
|
|
219
310
|
if (!this.socket) {
|
|
220
311
|
this.onMessage('not logged in');
|
|
@@ -289,6 +380,9 @@ export class PhantasmaLink {
|
|
|
289
380
|
//Sends Signiture Request To Connected Wallet For Script
|
|
290
381
|
this.sendLinkRequest('getNexus/', function (result) {
|
|
291
382
|
if (result.success) {
|
|
383
|
+
if (typeof result.nexus === 'string') {
|
|
384
|
+
that.nexus = result.nexus;
|
|
385
|
+
}
|
|
292
386
|
that.onMessage('Nexus Query,: ' + result);
|
|
293
387
|
if (callback) {
|
|
294
388
|
callback(result);
|
|
@@ -360,22 +454,31 @@ export class PhantasmaLink {
|
|
|
360
454
|
if (this.socket) {
|
|
361
455
|
this.socket.close();
|
|
362
456
|
}
|
|
457
|
+
const useInjectedSocket =
|
|
458
|
+
// @ts-ignore
|
|
459
|
+
!!window.PhantasmaLinkSocket && this.providerHint !== 'poltergeist';
|
|
460
|
+
this.socketTransport = useInjectedSocket ? 'injected' : 'websocket';
|
|
461
|
+
this.socketOpen = false;
|
|
462
|
+
this.onMessage(useInjectedSocket
|
|
463
|
+
? 'Using injected PhantasmaLinkSocket transport'
|
|
464
|
+
: `Using raw WebSocket transport: ${path}`);
|
|
363
465
|
//@ts-ignore
|
|
364
|
-
this.socket =
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
: new WebSocket(path);
|
|
466
|
+
this.socket = useInjectedSocket
|
|
467
|
+
? // @ts-ignore
|
|
468
|
+
new PhantasmaLinkSocket()
|
|
469
|
+
: new WebSocket(path);
|
|
369
470
|
this.requestCallback = null;
|
|
370
471
|
this.lastSocketErrorMessage = null;
|
|
371
472
|
this.token = null;
|
|
372
473
|
this.account = null;
|
|
474
|
+
this.nexus = '';
|
|
373
475
|
this.requestID = 0;
|
|
374
476
|
let authorizeRequest = 'authorize/' + this.dapp + '/' + this.version;
|
|
375
477
|
let getAccountRequest = 'getAccount/' + this.platform;
|
|
376
478
|
let that = this;
|
|
377
479
|
//Once Socket Opened
|
|
378
480
|
this.socket.onopen = function (e) {
|
|
481
|
+
that.socketOpen = true;
|
|
379
482
|
that.onMessage('Connection established, authorizing dapp in wallet...');
|
|
380
483
|
if (isResume) {
|
|
381
484
|
that.fetchWallet(undefined, undefined);
|
|
@@ -386,6 +489,7 @@ export class PhantasmaLink {
|
|
|
386
489
|
if (result.success) {
|
|
387
490
|
that.token = result.token;
|
|
388
491
|
that.wallet = result.wallet;
|
|
492
|
+
that.nexus = typeof result.nexus === 'string' ? result.nexus : '';
|
|
389
493
|
that.onMessage('Authorized, obtaining account info...');
|
|
390
494
|
that.sendLinkRequest(getAccountRequest, function (result) {
|
|
391
495
|
if (result.success) {
|
|
@@ -402,7 +506,7 @@ export class PhantasmaLink {
|
|
|
402
506
|
});
|
|
403
507
|
}
|
|
404
508
|
else {
|
|
405
|
-
that.onError('Authorization failed...');
|
|
509
|
+
that.onError(that.describeFailure(result, 'Authorization failed...'));
|
|
406
510
|
that.disconnect('Auth Failure');
|
|
407
511
|
}
|
|
408
512
|
});
|
|
@@ -425,8 +529,9 @@ export class PhantasmaLink {
|
|
|
425
529
|
that.onError('Could not obtain account info... Make sure you have an account currently logged in');
|
|
426
530
|
that.disconnect(true);
|
|
427
531
|
break;
|
|
428
|
-
case 'A previouus request is still pending'
|
|
429
|
-
|
|
532
|
+
case 'A previouus request is still pending':
|
|
533
|
+
case 'A previous request is still pending':
|
|
534
|
+
that.onError(that.describeFailure(obj, 'You have a pending action in your wallet'));
|
|
430
535
|
break;
|
|
431
536
|
case 'user rejected':
|
|
432
537
|
that.onError('Transaction cancelled by user in ' + that.wallet);
|
|
@@ -452,6 +557,7 @@ export class PhantasmaLink {
|
|
|
452
557
|
};
|
|
453
558
|
//Cleanup After Socket Closes
|
|
454
559
|
this.socket.onclose = function (event) {
|
|
560
|
+
that.socketOpen = false;
|
|
455
561
|
const reason = event.reason && event.reason.length > 0
|
|
456
562
|
? event.reason
|
|
457
563
|
: that.lastSocketErrorMessage || (event.wasClean ? 'Wallet connection closed' : 'Connection terminated unexpectedly');
|
|
@@ -502,8 +608,11 @@ export class PhantasmaLink {
|
|
|
502
608
|
this.requestCallback = callback;
|
|
503
609
|
const socket = this.socket;
|
|
504
610
|
const openState = typeof WebSocket !== 'undefined' && typeof WebSocket.OPEN === 'number' ? WebSocket.OPEN : 1;
|
|
505
|
-
const
|
|
506
|
-
|
|
611
|
+
const hasSend = socket && typeof socket.send === 'function';
|
|
612
|
+
const hasReadyState = socket && typeof socket.readyState === 'number';
|
|
613
|
+
const isSocketOpen = hasSend &&
|
|
614
|
+
(hasReadyState ? socket.readyState === openState : this.socketOpen);
|
|
615
|
+
if (!socket || !hasSend || !isSocketOpen) {
|
|
507
616
|
this.handleSocketFailure('Wallet connection is closed. Please reconnect to your wallet.');
|
|
508
617
|
return;
|
|
509
618
|
}
|
|
@@ -537,6 +646,7 @@ export class PhantasmaLink {
|
|
|
537
646
|
//Disconnect The Wallet Connection Socket
|
|
538
647
|
disconnect(triggered) {
|
|
539
648
|
this.onMessage('Disconnecting Phantasma Link: ' + triggered);
|
|
649
|
+
this.socketOpen = false;
|
|
540
650
|
if (this.socket)
|
|
541
651
|
this.socket.close();
|
|
542
652
|
}
|
|
@@ -2,6 +2,7 @@ import { PhantasmaLink } from './phantasmaLink.js';
|
|
|
2
2
|
import { ProofOfWork } from './interfaces/ProofOfWork.js';
|
|
3
3
|
import { EasyScript, Nexus } from './easyScript.js';
|
|
4
4
|
import { TxMsg } from '../types/Carbon/Blockchain/index.js';
|
|
5
|
+
import { Transaction } from '../tx/Transaction.js';
|
|
5
6
|
export declare class EasyConnect {
|
|
6
7
|
requiredVersion: number;
|
|
7
8
|
platform: string;
|
|
@@ -9,7 +10,7 @@ export declare class EasyConnect {
|
|
|
9
10
|
link: PhantasmaLink;
|
|
10
11
|
connected: boolean;
|
|
11
12
|
script: EasyScript;
|
|
12
|
-
nexus: Nexus;
|
|
13
|
+
nexus: Nexus | null;
|
|
13
14
|
constructor(_options?: Array<string>);
|
|
14
15
|
setConfig(_provider: string): void;
|
|
15
16
|
connect(onSuccess?: any, onFail?: any): void;
|
|
@@ -19,6 +20,7 @@ export declare class EasyConnect {
|
|
|
19
20
|
signTransaction(script: string, payload?: any, onSuccess?: any, onFail?: any): void;
|
|
20
21
|
signData(data: any, onSuccess?: any, onFail?: any): void;
|
|
21
22
|
signCarbonTransaction(txMsg: TxMsg, onSuccess?: any, onFail?: any): void;
|
|
23
|
+
signPrebuiltTransaction(tx: Transaction, onSuccess?: any, onFail?: any): void;
|
|
22
24
|
invokeScript(script: string, _callback: any): void;
|
|
23
25
|
deployContract(script: string, payload?: any, proofOfWork?: ProofOfWork, onSuccess?: any, onFail?: any): void;
|
|
24
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"easyConnect.d.ts","sourceRoot":"","sources":["../../../../src/core/link/easyConnect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"easyConnect.d.ts","sourceRoot":"","sources":["../../../../src/core/link/easyConnect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD,qBAAa,WAAW;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;gBAER,QAAQ,GAAE,KAAK,CAAC,MAAM,CAAQ;IAwB1C,SAAS,CAAC,SAAS,EAAE,MAAM;IAwB3B,OAAO,CACL,SAAS,GAAE,GAAkB,EAC7B,MAAM,GAAE,GAEP;IAgCH,UAAU,CAAC,QAAQ,GAAE,MAA6B;IAM5C,KAAK,CACT,KAAK,GAAE,MAAa,EACpB,UAAU,GAAE,KAAK,CAAC,MAAM,CAAQ,EAChC,SAAS,GAAE,GAEV;IA4CG,MAAM,CACV,KAAK,GAAE,MAAa,EACpB,UAAU,GAAE,KAAK,CAAC,GAAG,CAAQ,EAC7B,SAAS,GAAE,GAAkB,EAC7B,MAAM,GAAE,GAEP;IAyBH,eAAe,CACb,MAAM,EAAE,MAAM,EACd,OAAO,MAAO,EACd,SAAS,GAAE,GAAkB,EAC7B,MAAM,GAAE,GAEP;IAKH,QAAQ,CACN,IAAI,EAAE,GAAG,EACT,SAAS,GAAE,GAAkB,EAC7B,MAAM,GAAE,GAEP;IAKH,qBAAqB,CACnB,KAAK,EAAE,KAAK,EACZ,SAAS,GAAE,GAAkB,EAC7B,MAAM,GAAE,GAEP;IAWH,uBAAuB,CACrB,EAAE,EAAE,WAAW,EACf,SAAS,GAAE,GAAkB,EAC7B,MAAM,GAAE,GAEP;IAWH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG;IAI3C,cAAc,CACZ,MAAM,EAAE,MAAM,EACd,OAAO,MAAO,EACd,WAAW,GAAE,WAAiC,EAC9C,SAAS,GAAE,GAAkB,EAC7B,MAAM,GAAE,GAEP;CAIJ"}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import { Transaction } from '../tx/Transaction.js';
|
|
1
2
|
import { ProofOfWork } from './interfaces/ProofOfWork.js';
|
|
2
3
|
import { IAccount } from './interfaces/IAccount.js';
|
|
3
4
|
import { TxMsg } from '../types/Carbon/Blockchain/index.js';
|
|
5
|
+
export interface PrebuiltTransactionSignResult {
|
|
6
|
+
success: true;
|
|
7
|
+
signature: string;
|
|
8
|
+
signedTx: string;
|
|
9
|
+
}
|
|
4
10
|
export declare class PhantasmaLink {
|
|
5
11
|
host: string;
|
|
6
12
|
dapp: any;
|
|
@@ -10,6 +16,8 @@ export declare class PhantasmaLink {
|
|
|
10
16
|
socket: any;
|
|
11
17
|
requestCallback: any;
|
|
12
18
|
private lastSocketErrorMessage;
|
|
19
|
+
socketTransport: 'websocket' | 'injected' | null;
|
|
20
|
+
socketOpen: boolean;
|
|
13
21
|
token: any;
|
|
14
22
|
requestID: number;
|
|
15
23
|
account: IAccount;
|
|
@@ -21,11 +29,14 @@ export declare class PhantasmaLink {
|
|
|
21
29
|
platform: string;
|
|
22
30
|
constructor(dappID: any, logging?: boolean);
|
|
23
31
|
onMessage: (msg: string) => void;
|
|
32
|
+
private describeFailure;
|
|
24
33
|
login(onLoginCallback: (success: boolean) => void, onErrorCallback: (message: string) => void, version?: number, platform?: string, providerHint?: string): void;
|
|
25
34
|
invokeScript(script: string, callback: (message: string) => void): void;
|
|
26
35
|
signTx(script: any, payload: string | null, callback: (arg0: string) => void, onErrorCallback: () => void, pow?: ProofOfWork, signature?: string): void;
|
|
27
36
|
signCarbonTxAndBroadcast(txMsg: TxMsg, callback?: (result: any) => void, onErrorCallback?: (message?: string) => void): void;
|
|
28
|
-
signTxSignature(tx: string, callback: (result: string) => void, onErrorCallback: () => void, signature?: string): void;
|
|
37
|
+
signTxSignature(tx: string, callback: (result: string) => void, onErrorCallback: (message?: string) => void, signature?: string): void;
|
|
38
|
+
private decodeWalletSignatureBytes;
|
|
39
|
+
signPrebuiltTransaction(tx: Transaction, callback: (result: PrebuiltTransactionSignResult) => void, onErrorCallback: (message?: string) => void, signature?: string): void;
|
|
29
40
|
multiSig(subject: string, callback: (result: string) => void, onErrorCallback: () => void, signature?: string): void;
|
|
30
41
|
getPeer(callback: (result: string) => void, onErrorCallback: () => void): void;
|
|
31
42
|
fetchWallet(callback: (result: any) => void, onErrorCallback: (message: any) => void): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phantasmaLink.d.ts","sourceRoot":"","sources":["../../../../src/core/link/phantasmaLink.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"phantasmaLink.d.ts","sourceRoot":"","sources":["../../../../src/core/link/phantasmaLink.ts"],"names":[],"mappings":"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"}
|