phantasma-sdk-ts 0.5.1 → 0.6.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.
@@ -10,6 +10,8 @@ class PhantasmaLink {
10
10
  //Construct The Link
11
11
  constructor(dappID, logging = true) {
12
12
  this.lastSocketErrorMessage = null;
13
+ this.socketTransport = null;
14
+ this.socketOpen = false;
13
15
  this.requestID = 0;
14
16
  //Message Logging
15
17
  this.onMessage = (msg) => {
@@ -36,6 +38,19 @@ class PhantasmaLink {
36
38
  this.onLogin = function (succ) { }; //Does Nothing for Now
37
39
  this.onError = function (message) { }; //Does Nothing for Now
38
40
  }
41
+ // Preserve wallet-side failure details whenever the transport provides them.
42
+ describeFailure(result, fallback) {
43
+ if (typeof result === 'string' && result.length > 0) {
44
+ return result;
45
+ }
46
+ if (result && typeof result.error === 'string' && result.error.length > 0) {
47
+ return result.error;
48
+ }
49
+ if (result && typeof result.message === 'string' && result.message.length > 0) {
50
+ return result.message;
51
+ }
52
+ return fallback;
53
+ }
39
54
  //Connect To Wallet
40
55
  login(onLoginCallback, onErrorCallback, version = 4, platform = 'phantasma', providerHint = 'poltergeist') {
41
56
  this.providerHint = providerHint;
@@ -363,12 +378,19 @@ class PhantasmaLink {
363
378
  if (this.socket) {
364
379
  this.socket.close();
365
380
  }
381
+ const useInjectedSocket =
382
+ // @ts-ignore
383
+ !!window.PhantasmaLinkSocket && this.providerHint !== 'poltergeist';
384
+ this.socketTransport = useInjectedSocket ? 'injected' : 'websocket';
385
+ this.socketOpen = false;
386
+ this.onMessage(useInjectedSocket
387
+ ? 'Using injected PhantasmaLinkSocket transport'
388
+ : `Using raw WebSocket transport: ${path}`);
366
389
  //@ts-ignore
367
- this.socket = //@ts-ignore
368
- window.PhantasmaLinkSocket && this.providerHint !== 'poltergeist'
369
- ? // @ts-ignore
370
- new PhantasmaLinkSocket()
371
- : new WebSocket(path);
390
+ this.socket = useInjectedSocket
391
+ ? // @ts-ignore
392
+ new PhantasmaLinkSocket()
393
+ : new WebSocket(path);
372
394
  this.requestCallback = null;
373
395
  this.lastSocketErrorMessage = null;
374
396
  this.token = null;
@@ -379,6 +401,7 @@ class PhantasmaLink {
379
401
  let that = this;
380
402
  //Once Socket Opened
381
403
  this.socket.onopen = function (e) {
404
+ that.socketOpen = true;
382
405
  that.onMessage('Connection established, authorizing dapp in wallet...');
383
406
  if (isResume) {
384
407
  that.fetchWallet(undefined, undefined);
@@ -405,7 +428,7 @@ class PhantasmaLink {
405
428
  });
406
429
  }
407
430
  else {
408
- that.onError('Authorization failed...');
431
+ that.onError(that.describeFailure(result, 'Authorization failed...'));
409
432
  that.disconnect('Auth Failure');
410
433
  }
411
434
  });
@@ -428,8 +451,9 @@ class PhantasmaLink {
428
451
  that.onError('Could not obtain account info... Make sure you have an account currently logged in');
429
452
  that.disconnect(true);
430
453
  break;
431
- case 'A previouus request is still pending' || 'A previous request is still pending':
432
- that.onError('You have a pending action in your wallet');
454
+ case 'A previouus request is still pending':
455
+ case 'A previous request is still pending':
456
+ that.onError(that.describeFailure(obj, 'You have a pending action in your wallet'));
433
457
  break;
434
458
  case 'user rejected':
435
459
  that.onError('Transaction cancelled by user in ' + that.wallet);
@@ -455,6 +479,7 @@ class PhantasmaLink {
455
479
  };
456
480
  //Cleanup After Socket Closes
457
481
  this.socket.onclose = function (event) {
482
+ that.socketOpen = false;
458
483
  const reason = event.reason && event.reason.length > 0
459
484
  ? event.reason
460
485
  : that.lastSocketErrorMessage || (event.wasClean ? 'Wallet connection closed' : 'Connection terminated unexpectedly');
@@ -505,8 +530,11 @@ class PhantasmaLink {
505
530
  this.requestCallback = callback;
506
531
  const socket = this.socket;
507
532
  const openState = typeof WebSocket !== 'undefined' && typeof WebSocket.OPEN === 'number' ? WebSocket.OPEN : 1;
508
- const isSocketOpen = socket && socket.readyState === openState;
509
- if (!socket || !isSocketOpen) {
533
+ const hasSend = socket && typeof socket.send === 'function';
534
+ const hasReadyState = socket && typeof socket.readyState === 'number';
535
+ const isSocketOpen = hasSend &&
536
+ (hasReadyState ? socket.readyState === openState : this.socketOpen);
537
+ if (!socket || !hasSend || !isSocketOpen) {
510
538
  this.handleSocketFailure('Wallet connection is closed. Please reconnect to your wallet.');
511
539
  return;
512
540
  }
@@ -540,6 +568,7 @@ class PhantasmaLink {
540
568
  //Disconnect The Wallet Connection Socket
541
569
  disconnect(triggered) {
542
570
  this.onMessage('Disconnecting Phantasma Link: ' + triggered);
571
+ this.socketOpen = false;
543
572
  if (this.socket)
544
573
  this.socket.close();
545
574
  }
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildContractArtifactBundle = exports.buildContractArtifactManifest = exports.coerceContractBytes = exports.normalizeContractName = void 0;
7
+ const sha256_js_1 = __importDefault(require("crypto-js/sha256.js"));
8
+ const enc_hex_js_1 = __importDefault(require("crypto-js/enc-hex.js"));
9
+ const index_js_1 = require("../utils/index.js");
10
+ function sha256Hex(bytes) {
11
+ return (0, sha256_js_1.default)(enc_hex_js_1.default.parse((0, index_js_1.bytesToHex)(bytes))).toString(enc_hex_js_1.default);
12
+ }
13
+ function buildFileEntry(path, bytes) {
14
+ const trimmedPath = path.trim();
15
+ if (!trimmedPath) {
16
+ throw new Error('artifact path cannot be empty');
17
+ }
18
+ return {
19
+ path: trimmedPath,
20
+ size: bytes.length,
21
+ sha256: sha256Hex(bytes),
22
+ };
23
+ }
24
+ function normalizeContractName(contractName) {
25
+ const trimmed = contractName.trim();
26
+ if (!trimmed) {
27
+ throw new Error('contractName cannot be empty');
28
+ }
29
+ return trimmed;
30
+ }
31
+ exports.normalizeContractName = normalizeContractName;
32
+ function coerceContractBytes(input, label) {
33
+ if (input instanceof Uint8Array) {
34
+ if (input.length === 0) {
35
+ throw new Error(`${label} cannot be empty`);
36
+ }
37
+ // Copy mutable buffers so callers can keep reusing their original arrays safely.
38
+ return new Uint8Array(input);
39
+ }
40
+ if (typeof input === 'string') {
41
+ const trimmed = input.trim();
42
+ if (!trimmed) {
43
+ throw new Error(`${label} cannot be empty`);
44
+ }
45
+ const bytes = (0, index_js_1.hexToBytes)(trimmed);
46
+ if (bytes.length === 0) {
47
+ throw new Error(`${label} cannot be empty`);
48
+ }
49
+ return bytes;
50
+ }
51
+ throw new Error(`${label} must be Uint8Array or hex string`);
52
+ }
53
+ exports.coerceContractBytes = coerceContractBytes;
54
+ function buildContractArtifactManifest(params) {
55
+ // The manifest is the stable handoff contract between compiler, CLI, frontend, and runbooks.
56
+ const contractName = normalizeContractName(params.contractName);
57
+ const compilerName = params.compilerName.trim();
58
+ const compilerVersion = params.compilerVersion.trim();
59
+ if (!compilerName) {
60
+ throw new Error('compilerName cannot be empty');
61
+ }
62
+ if (!compilerVersion) {
63
+ throw new Error('compilerVersion cannot be empty');
64
+ }
65
+ const scriptBytes = coerceContractBytes(params.script, 'script');
66
+ const abiBytes = coerceContractBytes(params.abi, 'abi');
67
+ let debugEntry;
68
+ if (params.debugPath !== undefined || params.debug !== undefined) {
69
+ if (!params.debugPath || params.debug === undefined) {
70
+ throw new Error('debugPath and debug must be provided together');
71
+ }
72
+ debugEntry = buildFileEntry(params.debugPath, coerceContractBytes(params.debug, 'debug'));
73
+ }
74
+ const manifest = {
75
+ format: 'pha.contract.artifacts/v1',
76
+ contractName,
77
+ createdAtUtc: (params.createdAtUtc ?? new Date().toISOString()).trim(),
78
+ compiler: {
79
+ name: compilerName,
80
+ version: compilerVersion,
81
+ },
82
+ files: {
83
+ script: buildFileEntry(params.scriptPath, scriptBytes),
84
+ abi: buildFileEntry(params.abiPath, abiBytes),
85
+ ...(debugEntry ? { debug: debugEntry } : {}),
86
+ },
87
+ ...(params.sourceFile ? { sourceFile: params.sourceFile } : {}),
88
+ };
89
+ if (!manifest.createdAtUtc) {
90
+ throw new Error('createdAtUtc cannot be empty');
91
+ }
92
+ return manifest;
93
+ }
94
+ exports.buildContractArtifactManifest = buildContractArtifactManifest;
95
+ function buildContractArtifactBundle(params) {
96
+ // Keep bundle materialization small and explicit so higher layers can choose their own IO/layout policy.
97
+ const bundle = {
98
+ contractName: normalizeContractName(params.contractName),
99
+ script: coerceContractBytes(params.script, 'script'),
100
+ abi: coerceContractBytes(params.abi, 'abi'),
101
+ ...(params.debug !== undefined ? { debug: coerceContractBytes(params.debug, 'debug') } : {}),
102
+ ...(params.manifest ? { manifest: params.manifest } : {}),
103
+ };
104
+ return bundle;
105
+ }
106
+ exports.buildContractArtifactBundle = buildContractArtifactBundle;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContractTxHelper = void 0;
4
+ const ProofOfWork_js_1 = require("../link/interfaces/ProofOfWork.js");
5
+ const DomainSettings_js_1 = require("../types/DomainSettings.js");
6
+ const index_js_1 = require("../utils/index.js");
7
+ const index_js_2 = require("../vm/index.js");
8
+ const Transaction_js_1 = require("./Transaction.js");
9
+ const ContractArtifacts_js_1 = require("./ContractArtifacts.js");
10
+ class ContractTxHelper {
11
+ static buildDeployScript(params) {
12
+ return this.buildContractLifecycleScript('Runtime.DeployContract', params);
13
+ }
14
+ static buildUpgradeScript(params) {
15
+ return this.buildContractLifecycleScript('Runtime.UpgradeContract', params);
16
+ }
17
+ static buildDeployTransaction(params) {
18
+ return this.buildContractLifecycleTransaction(this.buildDeployScript(params), params);
19
+ }
20
+ static buildUpgradeTransaction(params) {
21
+ return this.buildContractLifecycleTransaction(this.buildUpgradeScript(params), params);
22
+ }
23
+ static buildDeployTransactionAndEncode(params) {
24
+ const tx = this.buildDeployTransaction(params);
25
+ this.signTransaction(tx, params.signer, params.proofOfWork);
26
+ return tx.ToStringEncoded(true).toUpperCase();
27
+ }
28
+ static buildUpgradeTransactionAndEncode(params) {
29
+ const tx = this.buildUpgradeTransaction(params);
30
+ this.signTransaction(tx, params.signer, params.proofOfWork);
31
+ return tx.ToStringEncoded(true).toUpperCase();
32
+ }
33
+ static buildDeployScriptFromBundle(bundle, from, gasPrice, gasLimit) {
34
+ return this.buildDeployScript({
35
+ from,
36
+ contractName: bundle.contractName,
37
+ script: bundle.script,
38
+ abi: bundle.abi,
39
+ gasPrice,
40
+ gasLimit,
41
+ });
42
+ }
43
+ static buildUpgradeScriptFromBundle(bundle, from, gasPrice, gasLimit) {
44
+ return this.buildUpgradeScript({
45
+ from,
46
+ contractName: bundle.contractName,
47
+ script: bundle.script,
48
+ abi: bundle.abi,
49
+ gasPrice,
50
+ gasLimit,
51
+ });
52
+ }
53
+ static encodePayloadText(text) {
54
+ return (0, index_js_1.bytesToHex)(new TextEncoder().encode(text));
55
+ }
56
+ static buildContractLifecycleScript(interopName, params) {
57
+ // Keep deploy/upgrade on the same legacy VM script path so CLI and wallet flows generate identical transactions.
58
+ const fromAddress = this.normalizeAddress(params.from);
59
+ const contractName = (0, ContractArtifacts_js_1.normalizeContractName)(params.contractName);
60
+ const scriptBytes = (0, ContractArtifacts_js_1.coerceContractBytes)(params.script, 'script');
61
+ const abiBytes = (0, ContractArtifacts_js_1.coerceContractBytes)(params.abi, 'abi');
62
+ const gasPrice = this.normalizeSmallInteger(params.gasPrice ?? this.DefaultGasPrice, 'gasPrice');
63
+ const gasLimit = this.normalizeSmallInteger(params.gasLimit ?? this.DefaultGasLimit, 'gasLimit');
64
+ const nullAddress = new index_js_2.ScriptBuilder().NullAddress;
65
+ return new index_js_2.ScriptBuilder()
66
+ .BeginScript()
67
+ .AllowGas(fromAddress, nullAddress, gasPrice, gasLimit)
68
+ .CallInterop(interopName, [fromAddress, contractName, scriptBytes, abiBytes])
69
+ .SpendGas(fromAddress)
70
+ .EndScript();
71
+ }
72
+ static buildContractLifecycleTransaction(scriptHex, params) {
73
+ // Transaction construction stays separate from signing so callers can inspect or override the unsigned tx first.
74
+ const nexus = params.nexus.trim();
75
+ const chain = (params.chain ?? DomainSettings_js_1.DomainSettings.RootChainName).trim();
76
+ if (!nexus) {
77
+ throw new Error('nexus cannot be empty');
78
+ }
79
+ if (!chain) {
80
+ throw new Error('chain cannot be empty');
81
+ }
82
+ const payloadHex = params.payloadHex?.trim() ?? '';
83
+ return new Transaction_js_1.Transaction(nexus, chain, scriptHex, params.expiration ?? new Date(Date.now() + 5 * 60 * 1000), payloadHex);
84
+ }
85
+ static signTransaction(tx, signer, proofOfWork = ProofOfWork_js_1.ProofOfWork.Minimal) {
86
+ // Mining/signing is the only mutation stage; everything above should remain deterministic and side-effect free.
87
+ if (proofOfWork > 0) {
88
+ tx.mineTransaction(proofOfWork);
89
+ }
90
+ if (typeof signer === 'string') {
91
+ const trimmedWif = signer.trim();
92
+ if (!trimmedWif) {
93
+ throw new Error('signer WIF cannot be empty');
94
+ }
95
+ tx.sign(trimmedWif);
96
+ return;
97
+ }
98
+ tx.signWithKeys(signer);
99
+ }
100
+ static normalizeAddress(address) {
101
+ if (typeof address === 'string') {
102
+ const trimmed = address.trim();
103
+ if (!trimmed) {
104
+ throw new Error('from cannot be empty');
105
+ }
106
+ return trimmed;
107
+ }
108
+ return address;
109
+ }
110
+ static normalizeSmallInteger(value, label) {
111
+ const numeric = typeof value === 'bigint' ? Number(value) : value;
112
+ if (!Number.isSafeInteger(numeric) || numeric <= 0) {
113
+ throw new Error(`${label} must be a positive safe integer`);
114
+ }
115
+ return numeric;
116
+ }
117
+ }
118
+ exports.ContractTxHelper = ContractTxHelper;
119
+ ContractTxHelper.DefaultGasPrice = DomainSettings_js_1.DomainSettings.DefaultMinimumGasFee;
120
+ ContractTxHelper.DefaultGasLimit = 100000;
@@ -15,5 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./ExecutionState.js"), exports);
18
+ __exportStar(require("./ContractArtifacts.js"), exports);
19
+ __exportStar(require("./ContractTxHelper.js"), exports);
18
20
  __exportStar(require("./Transaction.js"), exports);
19
21
  __exportStar(require("./utils.js"), exports);
@@ -18,7 +18,7 @@ function bytesToHex(bytes) {
18
18
  exports.bytesToHex = bytesToHex;
19
19
  function hexToBytes(hex) {
20
20
  const trimmed = hex.trim();
21
- const normalized = trimmed.startsWith('0x') ? trimmed.slice(2) : trimmed;
21
+ const normalized = trimmed.startsWith('0x') || trimmed.startsWith('0X') ? trimmed.slice(2) : trimmed;
22
22
  if (normalized.length === 0) {
23
23
  return new Uint8Array();
24
24
  }
@@ -7,6 +7,8 @@ export class PhantasmaLink {
7
7
  //Construct The Link
8
8
  constructor(dappID, logging = true) {
9
9
  this.lastSocketErrorMessage = null;
10
+ this.socketTransport = null;
11
+ this.socketOpen = false;
10
12
  this.requestID = 0;
11
13
  //Message Logging
12
14
  this.onMessage = (msg) => {
@@ -33,6 +35,19 @@ export class PhantasmaLink {
33
35
  this.onLogin = function (succ) { }; //Does Nothing for Now
34
36
  this.onError = function (message) { }; //Does Nothing for Now
35
37
  }
38
+ // Preserve wallet-side failure details whenever the transport provides them.
39
+ describeFailure(result, fallback) {
40
+ if (typeof result === 'string' && result.length > 0) {
41
+ return result;
42
+ }
43
+ if (result && typeof result.error === 'string' && result.error.length > 0) {
44
+ return result.error;
45
+ }
46
+ if (result && typeof result.message === 'string' && result.message.length > 0) {
47
+ return result.message;
48
+ }
49
+ return fallback;
50
+ }
36
51
  //Connect To Wallet
37
52
  login(onLoginCallback, onErrorCallback, version = 4, platform = 'phantasma', providerHint = 'poltergeist') {
38
53
  this.providerHint = providerHint;
@@ -360,12 +375,19 @@ export class PhantasmaLink {
360
375
  if (this.socket) {
361
376
  this.socket.close();
362
377
  }
378
+ const useInjectedSocket =
379
+ // @ts-ignore
380
+ !!window.PhantasmaLinkSocket && this.providerHint !== 'poltergeist';
381
+ this.socketTransport = useInjectedSocket ? 'injected' : 'websocket';
382
+ this.socketOpen = false;
383
+ this.onMessage(useInjectedSocket
384
+ ? 'Using injected PhantasmaLinkSocket transport'
385
+ : `Using raw WebSocket transport: ${path}`);
363
386
  //@ts-ignore
364
- this.socket = //@ts-ignore
365
- window.PhantasmaLinkSocket && this.providerHint !== 'poltergeist'
366
- ? // @ts-ignore
367
- new PhantasmaLinkSocket()
368
- : new WebSocket(path);
387
+ this.socket = useInjectedSocket
388
+ ? // @ts-ignore
389
+ new PhantasmaLinkSocket()
390
+ : new WebSocket(path);
369
391
  this.requestCallback = null;
370
392
  this.lastSocketErrorMessage = null;
371
393
  this.token = null;
@@ -376,6 +398,7 @@ export class PhantasmaLink {
376
398
  let that = this;
377
399
  //Once Socket Opened
378
400
  this.socket.onopen = function (e) {
401
+ that.socketOpen = true;
379
402
  that.onMessage('Connection established, authorizing dapp in wallet...');
380
403
  if (isResume) {
381
404
  that.fetchWallet(undefined, undefined);
@@ -402,7 +425,7 @@ export class PhantasmaLink {
402
425
  });
403
426
  }
404
427
  else {
405
- that.onError('Authorization failed...');
428
+ that.onError(that.describeFailure(result, 'Authorization failed...'));
406
429
  that.disconnect('Auth Failure');
407
430
  }
408
431
  });
@@ -425,8 +448,9 @@ export class PhantasmaLink {
425
448
  that.onError('Could not obtain account info... Make sure you have an account currently logged in');
426
449
  that.disconnect(true);
427
450
  break;
428
- case 'A previouus request is still pending' || 'A previous request is still pending':
429
- that.onError('You have a pending action in your wallet');
451
+ case 'A previouus request is still pending':
452
+ case 'A previous request is still pending':
453
+ that.onError(that.describeFailure(obj, 'You have a pending action in your wallet'));
430
454
  break;
431
455
  case 'user rejected':
432
456
  that.onError('Transaction cancelled by user in ' + that.wallet);
@@ -452,6 +476,7 @@ export class PhantasmaLink {
452
476
  };
453
477
  //Cleanup After Socket Closes
454
478
  this.socket.onclose = function (event) {
479
+ that.socketOpen = false;
455
480
  const reason = event.reason && event.reason.length > 0
456
481
  ? event.reason
457
482
  : that.lastSocketErrorMessage || (event.wasClean ? 'Wallet connection closed' : 'Connection terminated unexpectedly');
@@ -502,8 +527,11 @@ export class PhantasmaLink {
502
527
  this.requestCallback = callback;
503
528
  const socket = this.socket;
504
529
  const openState = typeof WebSocket !== 'undefined' && typeof WebSocket.OPEN === 'number' ? WebSocket.OPEN : 1;
505
- const isSocketOpen = socket && socket.readyState === openState;
506
- if (!socket || !isSocketOpen) {
530
+ const hasSend = socket && typeof socket.send === 'function';
531
+ const hasReadyState = socket && typeof socket.readyState === 'number';
532
+ const isSocketOpen = hasSend &&
533
+ (hasReadyState ? socket.readyState === openState : this.socketOpen);
534
+ if (!socket || !hasSend || !isSocketOpen) {
507
535
  this.handleSocketFailure('Wallet connection is closed. Please reconnect to your wallet.');
508
536
  return;
509
537
  }
@@ -537,6 +565,7 @@ export class PhantasmaLink {
537
565
  //Disconnect The Wallet Connection Socket
538
566
  disconnect(triggered) {
539
567
  this.onMessage('Disconnecting Phantasma Link: ' + triggered);
568
+ this.socketOpen = false;
540
569
  if (this.socket)
541
570
  this.socket.close();
542
571
  }
@@ -0,0 +1,96 @@
1
+ import SHA256 from 'crypto-js/sha256.js';
2
+ import hexEncoding from 'crypto-js/enc-hex.js';
3
+ import { bytesToHex, hexToBytes } from '../utils/index.js';
4
+ function sha256Hex(bytes) {
5
+ return SHA256(hexEncoding.parse(bytesToHex(bytes))).toString(hexEncoding);
6
+ }
7
+ function buildFileEntry(path, bytes) {
8
+ const trimmedPath = path.trim();
9
+ if (!trimmedPath) {
10
+ throw new Error('artifact path cannot be empty');
11
+ }
12
+ return {
13
+ path: trimmedPath,
14
+ size: bytes.length,
15
+ sha256: sha256Hex(bytes),
16
+ };
17
+ }
18
+ export function normalizeContractName(contractName) {
19
+ const trimmed = contractName.trim();
20
+ if (!trimmed) {
21
+ throw new Error('contractName cannot be empty');
22
+ }
23
+ return trimmed;
24
+ }
25
+ export function coerceContractBytes(input, label) {
26
+ if (input instanceof Uint8Array) {
27
+ if (input.length === 0) {
28
+ throw new Error(`${label} cannot be empty`);
29
+ }
30
+ // Copy mutable buffers so callers can keep reusing their original arrays safely.
31
+ return new Uint8Array(input);
32
+ }
33
+ if (typeof input === 'string') {
34
+ const trimmed = input.trim();
35
+ if (!trimmed) {
36
+ throw new Error(`${label} cannot be empty`);
37
+ }
38
+ const bytes = hexToBytes(trimmed);
39
+ if (bytes.length === 0) {
40
+ throw new Error(`${label} cannot be empty`);
41
+ }
42
+ return bytes;
43
+ }
44
+ throw new Error(`${label} must be Uint8Array or hex string`);
45
+ }
46
+ export function buildContractArtifactManifest(params) {
47
+ // The manifest is the stable handoff contract between compiler, CLI, frontend, and runbooks.
48
+ const contractName = normalizeContractName(params.contractName);
49
+ const compilerName = params.compilerName.trim();
50
+ const compilerVersion = params.compilerVersion.trim();
51
+ if (!compilerName) {
52
+ throw new Error('compilerName cannot be empty');
53
+ }
54
+ if (!compilerVersion) {
55
+ throw new Error('compilerVersion cannot be empty');
56
+ }
57
+ const scriptBytes = coerceContractBytes(params.script, 'script');
58
+ const abiBytes = coerceContractBytes(params.abi, 'abi');
59
+ let debugEntry;
60
+ if (params.debugPath !== undefined || params.debug !== undefined) {
61
+ if (!params.debugPath || params.debug === undefined) {
62
+ throw new Error('debugPath and debug must be provided together');
63
+ }
64
+ debugEntry = buildFileEntry(params.debugPath, coerceContractBytes(params.debug, 'debug'));
65
+ }
66
+ const manifest = {
67
+ format: 'pha.contract.artifacts/v1',
68
+ contractName,
69
+ createdAtUtc: (params.createdAtUtc ?? new Date().toISOString()).trim(),
70
+ compiler: {
71
+ name: compilerName,
72
+ version: compilerVersion,
73
+ },
74
+ files: {
75
+ script: buildFileEntry(params.scriptPath, scriptBytes),
76
+ abi: buildFileEntry(params.abiPath, abiBytes),
77
+ ...(debugEntry ? { debug: debugEntry } : {}),
78
+ },
79
+ ...(params.sourceFile ? { sourceFile: params.sourceFile } : {}),
80
+ };
81
+ if (!manifest.createdAtUtc) {
82
+ throw new Error('createdAtUtc cannot be empty');
83
+ }
84
+ return manifest;
85
+ }
86
+ export function buildContractArtifactBundle(params) {
87
+ // Keep bundle materialization small and explicit so higher layers can choose their own IO/layout policy.
88
+ const bundle = {
89
+ contractName: normalizeContractName(params.contractName),
90
+ script: coerceContractBytes(params.script, 'script'),
91
+ abi: coerceContractBytes(params.abi, 'abi'),
92
+ ...(params.debug !== undefined ? { debug: coerceContractBytes(params.debug, 'debug') } : {}),
93
+ ...(params.manifest ? { manifest: params.manifest } : {}),
94
+ };
95
+ return bundle;
96
+ }
@@ -0,0 +1,116 @@
1
+ import { ProofOfWork } from '../link/interfaces/ProofOfWork.js';
2
+ import { DomainSettings } from '../types/DomainSettings.js';
3
+ import { bytesToHex } from '../utils/index.js';
4
+ import { ScriptBuilder } from '../vm/index.js';
5
+ import { Transaction } from './Transaction.js';
6
+ import { coerceContractBytes, normalizeContractName } from './ContractArtifacts.js';
7
+ export class ContractTxHelper {
8
+ static buildDeployScript(params) {
9
+ return this.buildContractLifecycleScript('Runtime.DeployContract', params);
10
+ }
11
+ static buildUpgradeScript(params) {
12
+ return this.buildContractLifecycleScript('Runtime.UpgradeContract', params);
13
+ }
14
+ static buildDeployTransaction(params) {
15
+ return this.buildContractLifecycleTransaction(this.buildDeployScript(params), params);
16
+ }
17
+ static buildUpgradeTransaction(params) {
18
+ return this.buildContractLifecycleTransaction(this.buildUpgradeScript(params), params);
19
+ }
20
+ static buildDeployTransactionAndEncode(params) {
21
+ const tx = this.buildDeployTransaction(params);
22
+ this.signTransaction(tx, params.signer, params.proofOfWork);
23
+ return tx.ToStringEncoded(true).toUpperCase();
24
+ }
25
+ static buildUpgradeTransactionAndEncode(params) {
26
+ const tx = this.buildUpgradeTransaction(params);
27
+ this.signTransaction(tx, params.signer, params.proofOfWork);
28
+ return tx.ToStringEncoded(true).toUpperCase();
29
+ }
30
+ static buildDeployScriptFromBundle(bundle, from, gasPrice, gasLimit) {
31
+ return this.buildDeployScript({
32
+ from,
33
+ contractName: bundle.contractName,
34
+ script: bundle.script,
35
+ abi: bundle.abi,
36
+ gasPrice,
37
+ gasLimit,
38
+ });
39
+ }
40
+ static buildUpgradeScriptFromBundle(bundle, from, gasPrice, gasLimit) {
41
+ return this.buildUpgradeScript({
42
+ from,
43
+ contractName: bundle.contractName,
44
+ script: bundle.script,
45
+ abi: bundle.abi,
46
+ gasPrice,
47
+ gasLimit,
48
+ });
49
+ }
50
+ static encodePayloadText(text) {
51
+ return bytesToHex(new TextEncoder().encode(text));
52
+ }
53
+ static buildContractLifecycleScript(interopName, params) {
54
+ // Keep deploy/upgrade on the same legacy VM script path so CLI and wallet flows generate identical transactions.
55
+ const fromAddress = this.normalizeAddress(params.from);
56
+ const contractName = normalizeContractName(params.contractName);
57
+ const scriptBytes = coerceContractBytes(params.script, 'script');
58
+ const abiBytes = coerceContractBytes(params.abi, 'abi');
59
+ const gasPrice = this.normalizeSmallInteger(params.gasPrice ?? this.DefaultGasPrice, 'gasPrice');
60
+ const gasLimit = this.normalizeSmallInteger(params.gasLimit ?? this.DefaultGasLimit, 'gasLimit');
61
+ const nullAddress = new ScriptBuilder().NullAddress;
62
+ return new ScriptBuilder()
63
+ .BeginScript()
64
+ .AllowGas(fromAddress, nullAddress, gasPrice, gasLimit)
65
+ .CallInterop(interopName, [fromAddress, contractName, scriptBytes, abiBytes])
66
+ .SpendGas(fromAddress)
67
+ .EndScript();
68
+ }
69
+ static buildContractLifecycleTransaction(scriptHex, params) {
70
+ // Transaction construction stays separate from signing so callers can inspect or override the unsigned tx first.
71
+ const nexus = params.nexus.trim();
72
+ const chain = (params.chain ?? DomainSettings.RootChainName).trim();
73
+ if (!nexus) {
74
+ throw new Error('nexus cannot be empty');
75
+ }
76
+ if (!chain) {
77
+ throw new Error('chain cannot be empty');
78
+ }
79
+ const payloadHex = params.payloadHex?.trim() ?? '';
80
+ return new Transaction(nexus, chain, scriptHex, params.expiration ?? new Date(Date.now() + 5 * 60 * 1000), payloadHex);
81
+ }
82
+ static signTransaction(tx, signer, proofOfWork = ProofOfWork.Minimal) {
83
+ // Mining/signing is the only mutation stage; everything above should remain deterministic and side-effect free.
84
+ if (proofOfWork > 0) {
85
+ tx.mineTransaction(proofOfWork);
86
+ }
87
+ if (typeof signer === 'string') {
88
+ const trimmedWif = signer.trim();
89
+ if (!trimmedWif) {
90
+ throw new Error('signer WIF cannot be empty');
91
+ }
92
+ tx.sign(trimmedWif);
93
+ return;
94
+ }
95
+ tx.signWithKeys(signer);
96
+ }
97
+ static normalizeAddress(address) {
98
+ if (typeof address === 'string') {
99
+ const trimmed = address.trim();
100
+ if (!trimmed) {
101
+ throw new Error('from cannot be empty');
102
+ }
103
+ return trimmed;
104
+ }
105
+ return address;
106
+ }
107
+ static normalizeSmallInteger(value, label) {
108
+ const numeric = typeof value === 'bigint' ? Number(value) : value;
109
+ if (!Number.isSafeInteger(numeric) || numeric <= 0) {
110
+ throw new Error(`${label} must be a positive safe integer`);
111
+ }
112
+ return numeric;
113
+ }
114
+ }
115
+ ContractTxHelper.DefaultGasPrice = DomainSettings.DefaultMinimumGasFee;
116
+ ContractTxHelper.DefaultGasLimit = 100000;
@@ -1,3 +1,5 @@
1
1
  export * from './ExecutionState.js';
2
+ export * from './ContractArtifacts.js';
3
+ export * from './ContractTxHelper.js';
2
4
  export * from './Transaction.js';
3
5
  export * from './utils.js';
@@ -14,7 +14,7 @@ export function bytesToHex(bytes) {
14
14
  }
15
15
  export function hexToBytes(hex) {
16
16
  const trimmed = hex.trim();
17
- const normalized = trimmed.startsWith('0x') ? trimmed.slice(2) : trimmed;
17
+ const normalized = trimmed.startsWith('0x') || trimmed.startsWith('0X') ? trimmed.slice(2) : trimmed;
18
18
  if (normalized.length === 0) {
19
19
  return new Uint8Array();
20
20
  }
@@ -10,6 +10,8 @@ export declare class PhantasmaLink {
10
10
  socket: any;
11
11
  requestCallback: any;
12
12
  private lastSocketErrorMessage;
13
+ socketTransport: 'websocket' | 'injected' | null;
14
+ socketOpen: boolean;
13
15
  token: any;
14
16
  requestID: number;
15
17
  account: IAccount;
@@ -21,6 +23,7 @@ export declare class PhantasmaLink {
21
23
  platform: string;
22
24
  constructor(dappID: any, logging?: boolean);
23
25
  onMessage: (msg: string) => void;
26
+ private describeFailure;
24
27
  login(onLoginCallback: (success: boolean) => void, onErrorCallback: (message: string) => void, version?: number, platform?: string, providerHint?: string): void;
25
28
  invokeScript(script: string, callback: (message: string) => void): void;
26
29
  signTx(script: any, payload: string | null, callback: (arg0: string) => void, onErrorCallback: () => void, pow?: ProofOfWork, signature?: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"phantasmaLink.d.ts","sourceRoot":"","sources":["../../../../src/core/link/phantasmaLink.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAK5D,qBAAa,aAAa;IAExB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,GAAG,CAAC;IACV,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAC7B,YAAY,EAAE,GAAG,CAAC;IAClB,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IAChC,MAAM,EAAE,GAAG,CAAC;IACZ,eAAe,EAAE,GAAG,CAAC;IACrB,OAAO,CAAC,sBAAsB,CAAuB;IACrD,KAAK,EAAE,GAAG,CAAC;IACX,SAAS,EAAE,MAAM,CAAK;IACtB,OAAO,EAAE,QAAQ,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC;IACZ,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;gBAGL,MAAM,EAAE,GAAG,EAAE,OAAO,GAAE,OAAc;IAuBhD,SAAS,QAAS,MAAM,UAItB;IAGF,KAAK,CACH,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,EAC3C,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,EAC1C,OAAO,GAAE,MAAU,EACnB,QAAQ,GAAE,MAAoB,EAC9B,YAAY,GAAE,MAAsB;IAYtC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;IAgChE,MAAM,CACJ,MAAM,EAAE,GAAG,EACX,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAChC,eAAe,EAAE,MAAM,IAAI,EAC3B,GAAG,cAAmB,EACtB,SAAS,SAAY;IAqEvB,wBAAwB,CACtB,KAAK,EAAE,KAAK,EACZ,QAAQ,GAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAe,EAC1C,eAAe,GAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,IAAe;IAoDxD,eAAe,CACb,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EAClC,eAAe,EAAE,MAAM,IAAI,EAC3B,SAAS,GAAE,MAAkB;IAqC/B,QAAQ,CACN,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EAClC,eAAe,EAAE,MAAM,IAAI,EAC3B,SAAS,GAAE,MAAkB;IAqC/B,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EAAE,eAAe,EAAE,MAAM,IAAI;IAmBvE,WAAW,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,EAAE,eAAe,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI;IAqBpF,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,EAAE,eAAe,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI;IAmBlF,gBAAgB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,EAAE,eAAe,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI;IAqB1F,QAAQ,CACN,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,EACnC,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,EAC1C,SAAS,GAAE,MAAkB;IAsC/B,YAAY,CAAC,QAAQ,GAAE,OAAe;IA0ItC,oBAAoB;IAQpB,MAAM,CAAC,KAAK,EAAE,GAAG;IAMjB,KAAK;IAKL,IAAI,MAAM,CAAC,IAAI,KAAA,EAEd;IAED,IAAI,MAAM,QAET;IAGD,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI;IAiC3D,OAAO,CAAC,mBAAmB;IAe3B,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAKlD,OAAO,CAAC,iBAAiB;CAK1B"}
1
+ {"version":3,"file":"phantasmaLink.d.ts","sourceRoot":"","sources":["../../../../src/core/link/phantasmaLink.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ export type ContractBinaryInput = Uint8Array | string;
2
+ export interface ContractArtifactFileEntry {
3
+ path: string;
4
+ size: number;
5
+ sha256: string;
6
+ }
7
+ export interface ContractArtifactManifest {
8
+ format: 'pha.contract.artifacts/v1';
9
+ contractName: string;
10
+ createdAtUtc: string;
11
+ compiler: {
12
+ name: string;
13
+ version: string;
14
+ };
15
+ sourceFile?: string;
16
+ files: {
17
+ script: ContractArtifactFileEntry;
18
+ abi: ContractArtifactFileEntry;
19
+ debug?: ContractArtifactFileEntry;
20
+ };
21
+ }
22
+ export interface ContractArtifactBundle {
23
+ contractName: string;
24
+ script: Uint8Array;
25
+ abi: Uint8Array;
26
+ debug?: Uint8Array;
27
+ manifest?: ContractArtifactManifest;
28
+ }
29
+ export interface BuildContractArtifactManifestParams {
30
+ contractName: string;
31
+ compilerName: string;
32
+ compilerVersion: string;
33
+ scriptPath: string;
34
+ script: ContractBinaryInput;
35
+ abiPath: string;
36
+ abi: ContractBinaryInput;
37
+ sourceFile?: string;
38
+ debugPath?: string;
39
+ debug?: ContractBinaryInput;
40
+ createdAtUtc?: string;
41
+ }
42
+ export interface BuildContractArtifactBundleParams {
43
+ contractName: string;
44
+ script: ContractBinaryInput;
45
+ abi: ContractBinaryInput;
46
+ debug?: ContractBinaryInput;
47
+ manifest?: ContractArtifactManifest;
48
+ }
49
+ export declare function normalizeContractName(contractName: string): string;
50
+ export declare function coerceContractBytes(input: ContractBinaryInput, label: string): Uint8Array;
51
+ export declare function buildContractArtifactManifest(params: BuildContractArtifactManifestParams): ContractArtifactManifest;
52
+ export declare function buildContractArtifactBundle(params: BuildContractArtifactBundleParams): ContractArtifactBundle;
53
+ //# sourceMappingURL=ContractArtifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContractArtifacts.d.ts","sourceRoot":"","sources":["../../../../src/core/tx/ContractArtifacts.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,MAAM,CAAC;AAEtD,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,2BAA2B,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE;QACL,MAAM,EAAE,yBAAyB,CAAC;QAClC,GAAG,EAAE,yBAAyB,CAAC;QAC/B,KAAK,CAAC,EAAE,yBAAyB,CAAC;KACnC,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,wBAAwB,CAAC;CACrC;AAED,MAAM,WAAW,mCAAmC;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,mBAAmB,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iCAAiC;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,GAAG,EAAE,mBAAmB,CAAC;IACzB,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,CAAC,EAAE,wBAAwB,CAAC;CACrC;AAmBD,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAOlE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAwBzF;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,mCAAmC,GAC1C,wBAAwB,CA6C1B;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,iCAAiC,GACxC,sBAAsB,CAWxB"}
@@ -0,0 +1,41 @@
1
+ import { Address } from '../types/Address.js';
2
+ import { PhantasmaKeys } from '../types/PhantasmaKeys.js';
3
+ import { Transaction } from './Transaction.js';
4
+ import { ContractArtifactBundle, ContractBinaryInput } from './ContractArtifacts.js';
5
+ export interface ContractScriptBuildParams {
6
+ from: string | Address;
7
+ contractName: string;
8
+ script: ContractBinaryInput;
9
+ abi: ContractBinaryInput;
10
+ gasPrice?: number | bigint;
11
+ gasLimit?: number | bigint;
12
+ }
13
+ export interface ContractTransactionBuildParams extends ContractScriptBuildParams {
14
+ nexus: string;
15
+ chain?: string;
16
+ expiration?: Date;
17
+ payloadHex?: string;
18
+ }
19
+ export interface ContractTransactionSignParams extends ContractTransactionBuildParams {
20
+ signer: string | PhantasmaKeys;
21
+ proofOfWork?: number;
22
+ }
23
+ export declare class ContractTxHelper {
24
+ static readonly DefaultGasPrice: number;
25
+ static readonly DefaultGasLimit = 100000;
26
+ static buildDeployScript(params: ContractScriptBuildParams): string;
27
+ static buildUpgradeScript(params: ContractScriptBuildParams): string;
28
+ static buildDeployTransaction(params: ContractTransactionBuildParams): Transaction;
29
+ static buildUpgradeTransaction(params: ContractTransactionBuildParams): Transaction;
30
+ static buildDeployTransactionAndEncode(params: ContractTransactionSignParams): string;
31
+ static buildUpgradeTransactionAndEncode(params: ContractTransactionSignParams): string;
32
+ static buildDeployScriptFromBundle(bundle: ContractArtifactBundle, from: string | Address, gasPrice?: number | bigint, gasLimit?: number | bigint): string;
33
+ static buildUpgradeScriptFromBundle(bundle: ContractArtifactBundle, from: string | Address, gasPrice?: number | bigint, gasLimit?: number | bigint): string;
34
+ static encodePayloadText(text: string): string;
35
+ private static buildContractLifecycleScript;
36
+ private static buildContractLifecycleTransaction;
37
+ private static signTransaction;
38
+ private static normalizeAddress;
39
+ private static normalizeSmallInteger;
40
+ }
41
+ //# sourceMappingURL=ContractTxHelper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContractTxHelper.d.ts","sourceRoot":"","sources":["../../../../src/core/tx/ContractTxHelper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAA8C,MAAM,wBAAwB,CAAC;AAEjI,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,GAAG,EAAE,mBAAmB,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,8BAA+B,SAAQ,yBAAyB;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,6BAA8B,SAAQ,8BAA8B;IACnF,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,eAAe,SAAuC;IACtE,MAAM,CAAC,QAAQ,CAAC,eAAe,UAAW;IAE1C,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM;IAInE,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM;IAIpE,MAAM,CAAC,sBAAsB,CAAC,MAAM,EAAE,8BAA8B,GAAG,WAAW;IAIlF,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,8BAA8B,GAAG,WAAW;IAInF,MAAM,CAAC,+BAA+B,CAAC,MAAM,EAAE,6BAA6B,GAAG,MAAM;IAMrF,MAAM,CAAC,gCAAgC,CAAC,MAAM,EAAE,6BAA6B,GAAG,MAAM;IAMtF,MAAM,CAAC,2BAA2B,CAAC,MAAM,EAAE,sBAAsB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAW1J,MAAM,CAAC,4BAA4B,CAAC,MAAM,EAAE,sBAAsB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAW3J,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI9C,OAAO,CAAC,MAAM,CAAC,4BAA4B;IAqB3C,OAAO,CAAC,MAAM,CAAC,iCAAiC;IAyBhD,OAAO,CAAC,MAAM,CAAC,eAAe;IAsB9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAY/B,OAAO,CAAC,MAAM,CAAC,qBAAqB;CAQrC"}
@@ -1,4 +1,6 @@
1
1
  export * from './ExecutionState.js';
2
+ export * from './ContractArtifacts.js';
3
+ export * from './ContractTxHelper.js';
2
4
  export * from './Transaction.js';
3
5
  export * from './utils.js';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/tx/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/tx/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phantasma-sdk-ts",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Typescript SDK for interacting with the Phantasma Chain",
5
5
  "author": "Phantasma Team",
6
6
  "main": "dist/cjs/index.js",