@locuschain/lib 0.0.16-beta.9 → 0.1.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.
@@ -3,162 +3,6 @@
3
3
  var addressClass = require('./address-class-Cjy48Uqk.cjs');
4
4
  var _ = require('lodash');
5
5
 
6
- // Automatically generated file. DO NOT EDIT.
7
- const callWasm = (cmd, params) => {
8
- // @ts-ignore
9
- let callLclib = globalThis['CallLclib'];
10
- if (LCLIB_NAMESPACE) {
11
- // @ts-ignore
12
- callLclib = globalThis[LCLIB_NAMESPACE]['CallLclib'];
13
- }
14
- // @ts-ignore
15
- if (typeof callLclib !== 'function')
16
- throw new Error('Wasm module is not loaded. Please call loadWasm or loadWasmSync first.');
17
- // @ts-ignore
18
- const resultString = callLclib(cmd, JSON.stringify(params));
19
- const result = JSON.parse(resultString);
20
- if (result.error && result.error.code != 0) {
21
- const error = Object.assign(Object.assign({}, result.error), { message: result.error.message });
22
- delete error.message;
23
- throw error;
24
- }
25
- else {
26
- return result.result;
27
- }
28
- };
29
- const calculateTxLinkHash = (params) => {
30
- return callWasm('calculateTxLinkHash', [params]);
31
- };
32
- const compileCoreScript = (params) => {
33
- return callWasm('compileCoreScript', [params]);
34
- };
35
- const convertAddressToData = (addrEncoded) => {
36
- return callWasm('convertAddressToData', [addrEncoded]);
37
- };
38
- const convertAddressToHex = (addrEncoded) => {
39
- return callWasm('convertAddressToHex', [addrEncoded]);
40
- };
41
- const convertBase32ToData = (encoded) => {
42
- return callWasm('convertBase32ToData', [encoded]);
43
- };
44
- const convertBase32ToHex = (encoded) => {
45
- return callWasm('convertBase32ToHex', [encoded]);
46
- };
47
- const convertCurrency = (params) => {
48
- return callWasm('convertCurrency', [params]);
49
- };
50
- const convertDataTo = (value, retType) => {
51
- return callWasm('convertDataTo', [value, retType]);
52
- };
53
- const convertDataToAddress = (str) => {
54
- return callWasm('convertDataToAddress', [str]);
55
- };
56
- const convertDataToBase32 = (str) => {
57
- return callWasm('convertDataToBase32', [str]);
58
- };
59
- const convertDataToHex = (str) => {
60
- return callWasm('convertDataToHex', [str]);
61
- };
62
- const convertDataToString = (str) => {
63
- return callWasm('convertDataToString', [str]);
64
- };
65
- const convertHexToAddress = (hexString) => {
66
- return callWasm('convertHexToAddress', [hexString]);
67
- };
68
- const convertHexToBase32 = (hexString) => {
69
- return callWasm('convertHexToBase32', [hexString]);
70
- };
71
- const convertHexToData = (encoded) => {
72
- return callWasm('convertHexToData', [encoded]);
73
- };
74
- const convertStringToData = (raw) => {
75
- return callWasm('convertStringToData', [raw]);
76
- };
77
- const convertToData = (value, valueType) => {
78
- return callWasm('convertToData', [value, valueType]);
79
- };
80
- const createAccountAndKeystore = (params) => {
81
- return callWasm('createAccountAndKeystore', [params]);
82
- };
83
- const createMasterKeystore = (params) => {
84
- return callWasm('createMasterKeystore', [params]);
85
- };
86
- const createNormalKey = (params) => {
87
- return callWasm('createNormalKey', [params]);
88
- };
89
- const createNormalKeystore = (params) => {
90
- return callWasm('createNormalKeystore', [params]);
91
- };
92
- const decodeTxs = (params) => {
93
- return callWasm('decodeTxs', [params]);
94
- };
95
- const deriveKeysFromMnemonic = (params) => {
96
- return callWasm('deriveKeysFromMnemonic', [params]);
97
- };
98
- const disCompileCoreScript = (params) => {
99
- return callWasm('disCompileCoreScript', [params]);
100
- };
101
- const encodeTxCurrency = (params) => {
102
- return callWasm('encodeTxCurrency', [params]);
103
- };
104
- const encodeTxNumber = (params) => {
105
- return callWasm('encodeTxNumber', [params]);
106
- };
107
- const generateMnemonic = (params) => {
108
- return callWasm('generateMnemonic', [params]);
109
- };
110
- const generateMnemonicBySeed = (params) => {
111
- return callWasm('generateMnemonicBySeed', [params]);
112
- };
113
- const getDefFromCoreScript = (params) => {
114
- return callWasm('getDefFromCoreScript', [params]);
115
- };
116
- const getHomeShard = (params) => {
117
- return callWasm('getHomeShard', [params]);
118
- };
119
- const getLibraryVersions = () => {
120
- return callWasm('getLibraryVersions', []);
121
- };
122
- const gzipAndEncode = (str) => {
123
- return callWasm('gzipAndEncode', [str]);
124
- };
125
- const hash = (params) => {
126
- return callWasm('hash', [params]);
127
- };
128
- const isGrantConsumingTx = (txTypeStr) => {
129
- return callWasm('isGrantConsumingTx', [txTypeStr]);
130
- };
131
- const loadMasterKeystore = (params) => {
132
- return callWasm('loadMasterKeystore', [params]);
133
- };
134
- const loadNormalKeystore = (params) => {
135
- return callWasm('loadNormalKeystore', [params]);
136
- };
137
- const makeCurrency = (params) => {
138
- return callWasm('makeCurrency', [params]);
139
- };
140
- const sign = (param) => {
141
- return callWasm('sign', [param]);
142
- };
143
- const signByMasterKey = (params) => {
144
- return callWasm('signByMasterKey', [params]);
145
- };
146
- const testCoreScript = (params) => {
147
- return callWasm('testCoreScript', [params]);
148
- };
149
- const verify = (params) => {
150
- return callWasm('verify', [params]);
151
- };
152
- const verifyByMasterKey = (params) => {
153
- return callWasm('verifyByMasterKey', [params]);
154
- };
155
- const verifyMerkleProof = (params) => {
156
- return callWasm('verifyMerkleProof', [params]);
157
- };
158
- const verifyTx = (jsonTx) => {
159
- return callWasm('verifyTx', [jsonTx]);
160
- };
161
-
162
6
  /******************************************************************************
163
7
  Copyright (c) Microsoft Corporation.
164
8
 
@@ -817,215 +661,161 @@ function load() {
817
661
  });
818
662
  }
819
663
 
820
- class TxValidator {
821
- constructor() {
822
- this.verifyTxParams = (rpcResult, params, options) => {
823
- try {
824
- if (options.targetTxHash) {
825
- const genHash = JSON.parse(verifyTx(JSON.stringify(rpcResult.tx))).hash;
826
- if (options.targetTxHash !== genHash) {
827
- console.warn(`[TxnIntegrityChecker] Tx hash not matched.`, options.targetTxHash, '!==', genHash);
828
- return { result: false, reason: 'tx verify fail' };
829
- }
830
- }
831
- const checks = [];
832
- const tx = rpcResult.tx;
833
- switch (tx.type) {
834
- case 'TX_TRANSFER_COIN':
835
- case 'TX_TRANSFER_COIN_FEE':
836
- checks.push(() => this.checkFields(params, tx, { to: 'target', amount: 'amount' }));
837
- break;
838
- case 'TX_TRANSFER_COIN_EXPRESS':
839
- checks.push(() => this.checkFields(params, tx, {
840
- to: 'target',
841
- amount: 'amount',
842
- 'source.owner': 'source.addr',
843
- 'source.height': 'source.index'
844
- }));
845
- break;
846
- case 'TX_CREATE_TOKEN':
847
- case 'TX_CREATE_TOKEN_FEE':
848
- checks.push(() => this.checkFields(params, tx, { tokenBalance: 'tokenBalance.v' }));
849
- break;
850
- case 'TX_TRANSFER_TOKEN':
851
- case 'TX_TRANSFER_TOKEN_FEE':
852
- checks.push(() => this.checkFields(params, tx, { to: 'target', amount: 'amount' }), () => this.checkComplexField(params, tx, {
853
- paramPath: 'tokenAmounts',
854
- txPath: 'tokens',
855
- paramTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.tokenId, a: d.amountToken })),
856
- txTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.t, a: d.a }))
857
- }));
858
- break;
859
- case 'TX_CREATE_ASSETOBJECT':
860
- case 'TX_CREATE_ASSETOBJECT_FEE':
861
- checks.push(() => this.checkFields(params, tx, Object.assign({
862
- assetType: 'object.type',
863
- metaData: 'object.metaData'
864
- }, (params.amount === '0' ? {} : { amount: 'object.amount' })))
865
- // TODO: params.operator !== tx.Object.Operator ("" !== "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHF3E")
866
- );
867
- break;
868
- case 'TX_TRANSFER_ASSETOBJECT':
869
- case 'TX_TRANSFER_ASSETOBJECT_FEE':
870
- checks.push(() => this.checkFields(params, tx, { to: 'target' }), () => this.checkFields(params, tx, {
871
- to: 'target',
872
- amount: 'assetObjects.assetObjects[0].targetObject.amount',
873
- assetId: 'assetObjects.assetObjects[0].targetObject.assetId'
874
- }));
875
- break;
876
- case 'TX_CREATE_CONTRACT':
877
- case 'TX_CREATE_CONTRACT_FEE':
878
- checks.push(() => this.checkFields(params, tx, {
879
- code: 'code',
880
- amount: 'amount',
881
- fuelLimit: 'fuelLimit',
882
- sysId: 'sysId',
883
- until: 'until'
884
- }, {
885
- contractAccount: 'target'
886
- }), () => this.checkComplexField(params, tx, {
887
- paramPath: 'tokenAmounts',
888
- txPath: 'tokens',
889
- paramTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.tokenId, a: d.amountToken })),
890
- txTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.t, a: d.a }))
891
- }));
892
- break;
893
- case 'TX_CALL_CONTRACT':
894
- case 'TX_CALL_CONTRACT_FEE':
895
- checks.push(() => this.checkFields(params, tx, {
896
- contractAccount: 'target',
897
- amount: 'amount',
898
- fuelLimit: 'fuelLimit',
899
- func: 'func',
900
- argData: 'argData'
901
- }), () => this.checkComplexField(params, tx, {
902
- paramPath: 'tokenAmounts',
903
- txPath: 'tokens',
904
- paramTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.tokenId, a: d.amountToken })),
905
- txTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.t, a: d.a }))
906
- })
907
- // TODO: tx.AssetObjects 는 아직 rpc가 만들어지지 않아서 확인을 하지 못했다
908
- );
909
- break;
910
- case 'TX_POST_DATA':
911
- case 'TX_POST_DATA_FEE':
912
- checks.push(() => this.checkFields(params, tx, { data: 'data', label: 'label' }));
913
- break;
914
- case 'TX_OPEN_ACCOUNT':
915
- checks.push(() => this.checkFields(params, tx, { account: 'addr', pk: 'key' }, {
916
- sender: 'refLink.addr',
917
- index: 'refLink.index'
918
- }));
919
- break;
920
- case 'TX_PROVIDE_SCRIPT':
921
- checks.push(() => this.checkFields(params, tx, {
922
- target: 'target',
923
- targetAfterTimeLock: 'targetAfterTimeLock',
924
- amount: 'amount'
925
- }), () => this.checkComplexField(params, tx, {
926
- paramPath: 'scriptProvide',
927
- txPath: 'scriptProvide',
928
- paramTransform: code => compileCoreScript(code),
929
- txTransform: code => code
930
- }), () => this.checkComplexField(params, tx, {
931
- paramPath: 'scriptAccept',
932
- txPath: 'scriptAccept',
933
- paramTransform: code => compileCoreScript(code),
934
- txTransform: code => code
935
- }), () => this.checkComplexField(params, tx, {
936
- paramPath: 'args',
937
- txPath: 'args',
938
- paramTransform: args => args !== null && args !== void 0 ? args : [],
939
- txTransform: args => args !== null && args !== void 0 ? args : []
940
- }));
941
- break;
942
- case 'TX_ACCEPT_SCRIPT':
943
- checks.push(() => this.checkFields(params, tx, { provider: 'refLink.addr', index: 'refLink.index' }), () => this.checkComplexField(params, tx, {
944
- paramPath: 'args',
945
- txPath: 'args',
946
- paramTransform: args => args !== null && args !== void 0 ? args : [],
947
- txTransform: args => args !== null && args !== void 0 ? args : []
948
- }) // 배열 비교라서..
949
- );
950
- break;
951
- case 'TX_CLOSE_ACCOUNT':
952
- checks.push(() => this.checkFields(params, tx, { to: 'target' }));
953
- break;
954
- case 'TX_BECOME_HOST':
955
- case 'TX_BECOME_GUEST':
956
- break;
957
- default:
958
- break;
959
- }
960
- for (const check of checks) {
961
- const result = check();
962
- if (result !== true)
963
- return result;
964
- }
965
- return { result: true, reason: 'success' };
966
- }
967
- catch (e) {
968
- console.error(e);
969
- return { result: false, reason: `tx verify fail. error: ${e.message}` };
970
- }
971
- };
972
- /**
973
- * params 객체와 tx 객체의 필드를 주어진 매핑에 따라 비교합니다.
974
- * @param params 파라미터 객체.
975
- * @param tx 검증할 트랜잭션 객체.
976
- * @param mapping 키는 `params`의 속성 경로, 값은 `tx`의 속성 경로인 객체.
977
- * @param optional mapping과 동일한 구조이나, `params` 값이 있을경우만 체크합니다. string은 빈문자열이 아닌 문자열, number는 0을 없다고 판단합니다
978
- * @returns 모든 필드가 일치하면 `true`, 실패 시 `IntegrityCheckResult` 객체를 반환합니다.
979
- */
980
- this.checkFields = (params, tx, mapping, optional) => {
981
- for (const paramKey in mapping) {
982
- const txKey = mapping[paramKey];
983
- const paramValue = this.getByPathIgnoreCase(params, paramKey);
984
- const txValue = _.get(tx, txKey);
985
- if (paramValue !== txValue) {
986
- return this.logAndFail(tx.type, paramKey, paramValue, txValue);
987
- }
988
- }
989
- for (const paramKey in optional !== null && optional !== void 0 ? optional : {}) {
990
- const txKey = optional[paramKey];
991
- const paramValue = this.getByPathIgnoreCase(params, paramKey);
992
- if (paramValue && paramValue !== '' && paramValue !== 0) {
993
- const txValue = _.get(tx, txKey);
994
- if (paramValue !== txValue) {
995
- return this.logAndFail(tx.type, paramKey, paramValue, txValue);
996
- }
997
- }
998
- }
999
- return true;
1000
- };
1001
- this.checkComplexField = (params, tx, { paramPath, txPath, paramTransform, txTransform }) => {
1002
- const paramValue = paramTransform(this.getByPathIgnoreCase(params, paramPath));
1003
- const txValue = txTransform(_.get(tx, txPath));
1004
- if (!_.isEqual(paramValue, txValue)) {
1005
- return this.logAndFail(tx.type, paramPath, paramValue, txValue);
1006
- }
1007
- return true;
1008
- };
664
+ // Automatically generated file. DO NOT EDIT.
665
+ const callWasm = (cmd, params) => {
666
+ // @ts-ignore
667
+ let callLclib = globalThis['CallLclib'];
668
+ if (namespace) {
669
+ // @ts-ignore
670
+ callLclib = globalThis[namespace]['CallLclib'];
1009
671
  }
1010
- logAndFail(txType, field, expected, actual) {
1011
- console.warn(`[TxnIntegrityChecker] ${txType} ${field}:`, expected, actual);
1012
- return { result: false, reason: 'tx integrity check fail', field };
672
+ // @ts-ignore
673
+ if (typeof callLclib !== 'function')
674
+ throw new Error('Wasm module is not loaded. Please call loadWasm or loadWasmSync first.');
675
+ // @ts-ignore
676
+ const resultString = callLclib(cmd, JSON.stringify(params));
677
+ const result = JSON.parse(resultString);
678
+ if (result.error && result.error.code != 0) {
679
+ const error = Object.assign(Object.assign({}, result.error), { message: result.error.message });
680
+ delete error.message;
681
+ throw error;
1013
682
  }
1014
- // 속성명의 대소문자를 무시하고 값을 구한다
1015
- getByPathIgnoreCase(obj, path) {
1016
- const keys = path.split('.');
1017
- let current = obj;
1018
- for (const key of keys) {
1019
- if (current === null || typeof current !== 'object')
1020
- return undefined;
1021
- const actualKey = Object.keys(current).find(k => k.toLowerCase() === key.toLowerCase());
1022
- if (actualKey === undefined)
1023
- return undefined;
1024
- current = current[actualKey];
1025
- }
1026
- return current;
683
+ else {
684
+ return result.result;
1027
685
  }
1028
- }
686
+ };
687
+ const calculateTxLinkHash = (params) => {
688
+ return callWasm('calculateTxLinkHash', [params]);
689
+ };
690
+ const compileCoreScript = (params) => {
691
+ return callWasm('compileCoreScript', [params]);
692
+ };
693
+ const convertAddressToData = (addrEncoded) => {
694
+ return callWasm('convertAddressToData', [addrEncoded]);
695
+ };
696
+ const convertAddressToHex = (addrEncoded) => {
697
+ return callWasm('convertAddressToHex', [addrEncoded]);
698
+ };
699
+ const convertBase32ToData = (encoded) => {
700
+ return callWasm('convertBase32ToData', [encoded]);
701
+ };
702
+ const convertBase32ToHex = (encoded) => {
703
+ return callWasm('convertBase32ToHex', [encoded]);
704
+ };
705
+ const convertCurrency = (params) => {
706
+ return callWasm('convertCurrency', [params]);
707
+ };
708
+ const convertDataTo = (value, retType) => {
709
+ return callWasm('convertDataTo', [value, retType]);
710
+ };
711
+ const convertDataToAddress = (str) => {
712
+ return callWasm('convertDataToAddress', [str]);
713
+ };
714
+ const convertDataToBase32 = (str) => {
715
+ return callWasm('convertDataToBase32', [str]);
716
+ };
717
+ const convertDataToHex = (str) => {
718
+ return callWasm('convertDataToHex', [str]);
719
+ };
720
+ const convertDataToString = (str) => {
721
+ return callWasm('convertDataToString', [str]);
722
+ };
723
+ const convertHexToAddress = (hexString) => {
724
+ return callWasm('convertHexToAddress', [hexString]);
725
+ };
726
+ const convertHexToBase32 = (hexString) => {
727
+ return callWasm('convertHexToBase32', [hexString]);
728
+ };
729
+ const convertHexToData = (encoded) => {
730
+ return callWasm('convertHexToData', [encoded]);
731
+ };
732
+ const convertStringToData = (raw) => {
733
+ return callWasm('convertStringToData', [raw]);
734
+ };
735
+ const convertToData = (value, valueType) => {
736
+ return callWasm('convertToData', [value, valueType]);
737
+ };
738
+ const createAccountAndKeystore = (params) => {
739
+ return callWasm('createAccountAndKeystore', [params]);
740
+ };
741
+ const createMasterKeystore = (params) => {
742
+ return callWasm('createMasterKeystore', [params]);
743
+ };
744
+ const createNormalKey = (params) => {
745
+ return callWasm('createNormalKey', [params]);
746
+ };
747
+ const createNormalKeystore = (params) => {
748
+ return callWasm('createNormalKeystore', [params]);
749
+ };
750
+ const decodeTxs = (params) => {
751
+ return callWasm('decodeTxs', [params]);
752
+ };
753
+ const deriveKeysFromMnemonic = (params) => {
754
+ return callWasm('deriveKeysFromMnemonic', [params]);
755
+ };
756
+ const disCompileCoreScript = (params) => {
757
+ return callWasm('disCompileCoreScript', [params]);
758
+ };
759
+ const encodeTxCurrency = (params) => {
760
+ return callWasm('encodeTxCurrency', [params]);
761
+ };
762
+ const encodeTxNumber = (params) => {
763
+ return callWasm('encodeTxNumber', [params]);
764
+ };
765
+ const generateMnemonic = (params) => {
766
+ return callWasm('generateMnemonic', [params]);
767
+ };
768
+ const generateMnemonicBySeed = (params) => {
769
+ return callWasm('generateMnemonicBySeed', [params]);
770
+ };
771
+ const getDefFromCoreScript = (params) => {
772
+ return callWasm('getDefFromCoreScript', [params]);
773
+ };
774
+ const getHomeShard = (params) => {
775
+ return callWasm('getHomeShard', [params]);
776
+ };
777
+ const getLibraryVersions = () => {
778
+ return callWasm('getLibraryVersions', []);
779
+ };
780
+ const gzipAndEncode = (str) => {
781
+ return callWasm('gzipAndEncode', [str]);
782
+ };
783
+ const hash = (params) => {
784
+ return callWasm('hash', [params]);
785
+ };
786
+ const isGrantConsumingTx = (txTypeStr) => {
787
+ return callWasm('isGrantConsumingTx', [txTypeStr]);
788
+ };
789
+ const loadMasterKeystore = (params) => {
790
+ return callWasm('loadMasterKeystore', [params]);
791
+ };
792
+ const loadNormalKeystore = (params) => {
793
+ return callWasm('loadNormalKeystore', [params]);
794
+ };
795
+ const makeCurrency = (params) => {
796
+ return callWasm('makeCurrency', [params]);
797
+ };
798
+ const sign = (param) => {
799
+ return callWasm('sign', [param]);
800
+ };
801
+ const signByMasterKey = (params) => {
802
+ return callWasm('signByMasterKey', [params]);
803
+ };
804
+ const testCoreScript = (params) => {
805
+ return callWasm('testCoreScript', [params]);
806
+ };
807
+ const verify = (params) => {
808
+ return callWasm('verify', [params]);
809
+ };
810
+ const verifyByMasterKey = (params) => {
811
+ return callWasm('verifyByMasterKey', [params]);
812
+ };
813
+ const verifyMerkleProof = (params) => {
814
+ return callWasm('verifyMerkleProof', [params]);
815
+ };
816
+ const verifyTx = (jsonTx) => {
817
+ return callWasm('verifyTx', [jsonTx]);
818
+ };
1029
819
 
1030
820
  // Automatically generated file. DO NOT EDIT.
1031
821
  const TX_CREATION_RPC_LIST = [
@@ -1514,12 +1304,220 @@ class Rpc {
1514
1304
  }
1515
1305
  }
1516
1306
 
1307
+ class TxValidator {
1308
+ constructor() {
1309
+ this.verifyTxParams = (rpcResult, params, options) => {
1310
+ try {
1311
+ if (options.targetTxHash) {
1312
+ const genHash = JSON.parse(verifyTx(JSON.stringify(rpcResult.tx))).hash;
1313
+ if (options.targetTxHash !== genHash) {
1314
+ console.warn(`[TxnIntegrityChecker] Tx hash not matched.`, options.targetTxHash, '!==', genHash);
1315
+ return { result: false, reason: 'tx verify fail' };
1316
+ }
1317
+ }
1318
+ const checks = [];
1319
+ const tx = rpcResult.tx;
1320
+ switch (tx.type) {
1321
+ case 'TX_TRANSFER_COIN':
1322
+ case 'TX_TRANSFER_COIN_FEE':
1323
+ checks.push(() => this.checkFields(params, tx, { to: 'target', amount: 'amount' }));
1324
+ break;
1325
+ case 'TX_TRANSFER_COIN_EXPRESS':
1326
+ checks.push(() => this.checkFields(params, tx, {
1327
+ to: 'target',
1328
+ amount: 'amount',
1329
+ 'source.owner': 'source.addr',
1330
+ 'source.height': 'source.index'
1331
+ }));
1332
+ break;
1333
+ case 'TX_CREATE_TOKEN':
1334
+ case 'TX_CREATE_TOKEN_FEE':
1335
+ checks.push(() => this.checkFields(params, tx, { tokenBalance: 'tokenBalance.v' }));
1336
+ break;
1337
+ case 'TX_TRANSFER_TOKEN':
1338
+ case 'TX_TRANSFER_TOKEN_FEE':
1339
+ checks.push(() => this.checkFields(params, tx, { to: 'target', amount: 'amount' }), () => this.checkComplexField(params, tx, {
1340
+ paramPath: 'tokenAmounts',
1341
+ txPath: 'tokens',
1342
+ paramTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.tokenId, a: d.amountToken })),
1343
+ txTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.t, a: d.a }))
1344
+ }));
1345
+ break;
1346
+ case 'TX_CREATE_ASSETOBJECT':
1347
+ case 'TX_CREATE_ASSETOBJECT_FEE':
1348
+ checks.push(() => this.checkFields(params, tx, Object.assign({
1349
+ assetType: 'object.type',
1350
+ metaData: 'object.metaData'
1351
+ }, (params.amount === '0' ? {} : { amount: 'object.amount' })))
1352
+ // TODO: params.operator !== tx.Object.Operator ("" !== "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHF3E")
1353
+ );
1354
+ break;
1355
+ case 'TX_TRANSFER_ASSETOBJECT':
1356
+ case 'TX_TRANSFER_ASSETOBJECT_FEE':
1357
+ checks.push(() => this.checkFields(params, tx, { to: 'target' }), () => this.checkFields(params, tx, {
1358
+ to: 'target',
1359
+ amount: 'assetObjects.assetObjects[0].targetObject.amount',
1360
+ assetId: 'assetObjects.assetObjects[0].targetObject.assetId'
1361
+ }));
1362
+ break;
1363
+ case 'TX_CREATE_CONTRACT':
1364
+ case 'TX_CREATE_CONTRACT_FEE':
1365
+ checks.push(() => this.checkFields(params, tx, {
1366
+ code: 'code',
1367
+ amount: 'amount',
1368
+ fuelLimit: 'fuelLimit',
1369
+ sysId: 'sysId',
1370
+ until: 'until'
1371
+ }, {
1372
+ contractAccount: 'target'
1373
+ }), () => this.checkComplexField(params, tx, {
1374
+ paramPath: 'tokenAmounts',
1375
+ txPath: 'tokens',
1376
+ paramTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.tokenId, a: d.amountToken })),
1377
+ txTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.t, a: d.a }))
1378
+ }));
1379
+ break;
1380
+ case 'TX_CALL_CONTRACT':
1381
+ case 'TX_CALL_CONTRACT_FEE':
1382
+ checks.push(() => this.checkFields(params, tx, {
1383
+ contractAccount: 'target',
1384
+ amount: 'amount',
1385
+ fuelLimit: 'fuelLimit',
1386
+ func: 'func',
1387
+ argData: 'argData'
1388
+ }), () => this.checkComplexField(params, tx, {
1389
+ paramPath: 'tokenAmounts',
1390
+ txPath: 'tokens',
1391
+ paramTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.tokenId, a: d.amountToken })),
1392
+ txTransform: tokens => (tokens !== null && tokens !== void 0 ? tokens : []).map((d) => ({ t: d.t, a: d.a }))
1393
+ })
1394
+ // TODO: tx.AssetObjects 는 아직 rpc가 만들어지지 않아서 확인을 하지 못했다
1395
+ );
1396
+ break;
1397
+ case 'TX_POST_DATA':
1398
+ case 'TX_POST_DATA_FEE':
1399
+ checks.push(() => this.checkFields(params, tx, { data: 'data', label: 'label' }));
1400
+ break;
1401
+ case 'TX_OPEN_ACCOUNT':
1402
+ checks.push(() => this.checkFields(params, tx, { account: 'addr', pk: 'key' }, {
1403
+ sender: 'refLink.addr',
1404
+ index: 'refLink.index'
1405
+ }));
1406
+ break;
1407
+ case 'TX_PROVIDE_SCRIPT':
1408
+ checks.push(() => this.checkFields(params, tx, {
1409
+ target: 'target',
1410
+ targetAfterTimeLock: 'targetAfterTimeLock',
1411
+ amount: 'amount'
1412
+ }), () => this.checkComplexField(params, tx, {
1413
+ paramPath: 'scriptProvide',
1414
+ txPath: 'scriptProvide',
1415
+ paramTransform: code => compileCoreScript(code),
1416
+ txTransform: code => code
1417
+ }), () => this.checkComplexField(params, tx, {
1418
+ paramPath: 'scriptAccept',
1419
+ txPath: 'scriptAccept',
1420
+ paramTransform: code => compileCoreScript(code),
1421
+ txTransform: code => code
1422
+ }), () => this.checkComplexField(params, tx, {
1423
+ paramPath: 'args',
1424
+ txPath: 'args',
1425
+ paramTransform: args => args !== null && args !== void 0 ? args : [],
1426
+ txTransform: args => args !== null && args !== void 0 ? args : []
1427
+ }));
1428
+ break;
1429
+ case 'TX_ACCEPT_SCRIPT':
1430
+ checks.push(() => this.checkFields(params, tx, { provider: 'refLink.addr', index: 'refLink.index' }), () => this.checkComplexField(params, tx, {
1431
+ paramPath: 'args',
1432
+ txPath: 'args',
1433
+ paramTransform: args => args !== null && args !== void 0 ? args : [],
1434
+ txTransform: args => args !== null && args !== void 0 ? args : []
1435
+ }) // 배열 비교라서..
1436
+ );
1437
+ break;
1438
+ case 'TX_CLOSE_ACCOUNT':
1439
+ checks.push(() => this.checkFields(params, tx, { to: 'target' }));
1440
+ break;
1441
+ case 'TX_BECOME_HOST':
1442
+ case 'TX_BECOME_GUEST':
1443
+ break;
1444
+ default:
1445
+ break;
1446
+ }
1447
+ for (const check of checks) {
1448
+ const result = check();
1449
+ if (result !== true)
1450
+ return result;
1451
+ }
1452
+ return { result: true, reason: 'success' };
1453
+ }
1454
+ catch (e) {
1455
+ console.error(e);
1456
+ return { result: false, reason: `tx verify fail. error: ${e.message}` };
1457
+ }
1458
+ };
1459
+ /**
1460
+ * params 객체와 tx 객체의 필드를 주어진 매핑에 따라 비교합니다.
1461
+ * @param params 파라미터 객체.
1462
+ * @param tx 검증할 트랜잭션 객체.
1463
+ * @param mapping 키는 `params`의 속성 경로, 값은 `tx`의 속성 경로인 객체.
1464
+ * @param optional mapping과 동일한 구조이나, `params` 값이 있을경우만 체크합니다. string은 빈문자열이 아닌 문자열, number는 0을 없다고 판단합니다
1465
+ * @returns 모든 필드가 일치하면 `true`, 실패 시 `IntegrityCheckResult` 객체를 반환합니다.
1466
+ */
1467
+ this.checkFields = (params, tx, mapping, optional) => {
1468
+ for (const paramKey in mapping) {
1469
+ const txKey = mapping[paramKey];
1470
+ const paramValue = this.getByPathIgnoreCase(params, paramKey);
1471
+ const txValue = _.get(tx, txKey);
1472
+ if (paramValue !== txValue) {
1473
+ return this.logAndFail(tx.type, paramKey, paramValue, txValue);
1474
+ }
1475
+ }
1476
+ for (const paramKey in optional !== null && optional !== void 0 ? optional : {}) {
1477
+ const txKey = optional[paramKey];
1478
+ const paramValue = this.getByPathIgnoreCase(params, paramKey);
1479
+ if (paramValue && paramValue !== '' && paramValue !== 0) {
1480
+ const txValue = _.get(tx, txKey);
1481
+ if (paramValue !== txValue) {
1482
+ return this.logAndFail(tx.type, paramKey, paramValue, txValue);
1483
+ }
1484
+ }
1485
+ }
1486
+ return true;
1487
+ };
1488
+ this.checkComplexField = (params, tx, { paramPath, txPath, paramTransform, txTransform }) => {
1489
+ const paramValue = paramTransform(this.getByPathIgnoreCase(params, paramPath));
1490
+ const txValue = txTransform(_.get(tx, txPath));
1491
+ if (!_.isEqual(paramValue, txValue)) {
1492
+ return this.logAndFail(tx.type, paramPath, paramValue, txValue);
1493
+ }
1494
+ return true;
1495
+ };
1496
+ }
1497
+ logAndFail(txType, field, expected, actual) {
1498
+ console.warn(`[TxnIntegrityChecker] ${txType} ${field}:`, expected, actual);
1499
+ return { result: false, reason: 'tx integrity check fail', field };
1500
+ }
1501
+ // 속성명의 대소문자를 무시하고 값을 구한다
1502
+ getByPathIgnoreCase(obj, path) {
1503
+ const keys = path.split('.');
1504
+ let current = obj;
1505
+ for (const key of keys) {
1506
+ if (current === null || typeof current !== 'object')
1507
+ return undefined;
1508
+ const actualKey = Object.keys(current).find(k => k.toLowerCase() === key.toLowerCase());
1509
+ if (actualKey === undefined)
1510
+ return undefined;
1511
+ current = current[actualKey];
1512
+ }
1513
+ return current;
1514
+ }
1515
+ }
1516
+
1517
1517
  const loadLocusWasm = load;
1518
1518
  const loadLocusWasmSync = loadSync;
1519
- const LCLIB_NAMESPACE = namespace;
1520
1519
  const txValidator = new TxValidator();
1521
1520
  const verifyTxParams = txValidator.verifyTxParams;
1522
- console.log('LCLIB_NAMESPACE:', LCLIB_NAMESPACE);
1523
1521
  const checkAddressType = (address) => {
1524
1522
  try {
1525
1523
  const hex = convertAddressToHex(address);
@@ -1545,7 +1543,6 @@ const isToken = (addressType) => addressType === addressClass.AddressClass.UserT
1545
1543
  addressType === addressClass.AddressClass.AssetNFT;
1546
1544
  const isSystemToken = (addressType) => addressType === addressClass.AddressClass.UserToken || addressType === addressClass.AddressClass.ContractToken;
1547
1545
 
1548
- exports.LCLIB_NAMESPACE = LCLIB_NAMESPACE;
1549
1546
  exports.Rpc = Rpc;
1550
1547
  exports.TX_CREATION_RPC_LIST = TX_CREATION_RPC_LIST;
1551
1548
  exports.__awaiter = __awaiter;