@subwallet/extension-base 1.0.2-2 → 1.0.3-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.
Files changed (151) hide show
  1. package/background/KoniTypes.d.ts +56 -40
  2. package/background/KoniTypes.js +11 -9
  3. package/background/errors/TransactionError.js +25 -1
  4. package/background/types.d.ts +10 -5
  5. package/cjs/background/KoniTypes.js +11 -9
  6. package/cjs/background/errors/TransactionError.js +24 -0
  7. package/cjs/constants/index.js +8 -26
  8. package/cjs/koni/api/dotsama/balance.js +49 -224
  9. package/cjs/koni/api/dotsama/transfer.js +34 -39
  10. package/cjs/koni/api/nft/acala_nft/index.js +7 -7
  11. package/cjs/koni/api/nft/bit.country/index.js +7 -6
  12. package/cjs/koni/api/nft/evm_nft/index.js +8 -3
  13. package/cjs/koni/api/nft/index.js +3 -6
  14. package/cjs/koni/api/nft/karura_nft/index.js +7 -6
  15. package/cjs/koni/api/nft/rmrk_nft/index.js +11 -1
  16. package/cjs/koni/api/nft/statemine_nft/index.js +7 -6
  17. package/cjs/koni/api/nft/unique_nft/index.js +5 -1
  18. package/cjs/koni/api/nft/wasm_nft/index.js +170 -111
  19. package/cjs/koni/api/nft/wasm_nft/utils.js +11 -7
  20. package/cjs/koni/api/staking/bonding/amplitude.js +13 -9
  21. package/cjs/koni/api/staking/bonding/astar.js +15 -13
  22. package/cjs/koni/api/staking/bonding/index.js +22 -10
  23. package/cjs/koni/api/staking/bonding/paraChain.js +85 -2
  24. package/cjs/koni/api/staking/bonding/relayChain.js +122 -16
  25. package/cjs/koni/api/staking/bonding/utils.js +27 -8
  26. package/cjs/koni/api/tokens/wasm/index.js +5 -4
  27. package/cjs/koni/api/tokens/wasm/utils.js +63 -0
  28. package/cjs/koni/api/xcm/polkadotXcm.js +1 -1
  29. package/cjs/koni/api/xcm/utils.js +18 -13
  30. package/cjs/koni/api/xcm/xTokens.js +1 -1
  31. package/cjs/koni/api/xcm/xcmPallet.js +9 -6
  32. package/cjs/koni/background/cron.js +171 -61
  33. package/cjs/koni/background/handlers/Extension.js +391 -207
  34. package/cjs/koni/background/handlers/State.js +49 -34
  35. package/cjs/koni/background/handlers/Tabs.js +50 -17
  36. package/cjs/koni/background/subscription.js +53 -28
  37. package/cjs/packageInfo.js +1 -1
  38. package/cjs/services/base/types.js +20 -0
  39. package/cjs/services/chain-service/handler/SubstrateChainHandler.js +13 -8
  40. package/cjs/services/chain-service/index.js +73 -49
  41. package/cjs/services/event-service/index.js +5 -1
  42. package/cjs/services/event-service/types.js +11 -1
  43. package/cjs/services/history-service/index.js +101 -50
  44. package/cjs/services/history-service/subsquid-multi-chain-history.js +13 -10
  45. package/cjs/services/keyring-service/index.js +11 -13
  46. package/cjs/services/migration-service/scripts/MigrateImportedToken.js +2 -1
  47. package/cjs/services/price-service/coingecko.js +0 -1
  48. package/cjs/services/price-service/index.js +71 -24
  49. package/cjs/services/request-service/handler/AuthRequestHandler.js +13 -7
  50. package/cjs/services/request-service/handler/EvmRequestHandler.js +8 -12
  51. package/cjs/services/request-service/index.js +14 -5
  52. package/cjs/services/storage-service/DatabaseService.js +66 -34
  53. package/cjs/services/storage-service/db-stores/Nft.js +7 -15
  54. package/cjs/services/storage-service/db-stores/Transaction.js +6 -10
  55. package/cjs/services/transaction-service/event-parser/index.js +20 -48
  56. package/cjs/services/transaction-service/index.js +104 -48
  57. package/cjs/services/transaction-service/utils.js +10 -8
  58. package/cjs/utils/address.js +10 -1
  59. package/cjs/utils/index.js +9 -15
  60. package/cjs/utils/promise.js +26 -0
  61. package/constants/index.d.ts +7 -13
  62. package/constants/index.js +7 -13
  63. package/koni/api/dotsama/balance.d.ts +0 -1
  64. package/koni/api/dotsama/balance.js +22 -197
  65. package/koni/api/dotsama/transfer.js +11 -16
  66. package/koni/api/nft/acala_nft/index.js +7 -7
  67. package/koni/api/nft/bit.country/index.js +7 -6
  68. package/koni/api/nft/evm_nft/index.js +7 -3
  69. package/koni/api/nft/index.d.ts +1 -2
  70. package/koni/api/nft/index.js +3 -6
  71. package/koni/api/nft/karura_nft/index.js +7 -6
  72. package/koni/api/nft/nft.d.ts +1 -0
  73. package/koni/api/nft/rmrk_nft/index.js +11 -1
  74. package/koni/api/nft/statemine_nft/index.js +7 -6
  75. package/koni/api/nft/unique_nft/index.js +5 -1
  76. package/koni/api/nft/wasm_nft/index.d.ts +0 -2
  77. package/koni/api/nft/wasm_nft/index.js +168 -109
  78. package/koni/api/nft/wasm_nft/utils.d.ts +7 -5
  79. package/koni/api/nft/wasm_nft/utils.js +7 -5
  80. package/koni/api/staking/bonding/amplitude.d.ts +0 -1
  81. package/koni/api/staking/bonding/amplitude.js +15 -10
  82. package/koni/api/staking/bonding/astar.js +8 -6
  83. package/koni/api/staking/bonding/index.d.ts +4 -1
  84. package/koni/api/staking/bonding/index.js +23 -13
  85. package/koni/api/staking/bonding/paraChain.d.ts +3 -0
  86. package/koni/api/staking/bonding/paraChain.js +86 -5
  87. package/koni/api/staking/bonding/relayChain.d.ts +5 -1
  88. package/koni/api/staking/bonding/relayChain.js +121 -18
  89. package/koni/api/staking/bonding/utils.d.ts +3 -2
  90. package/koni/api/staking/bonding/utils.js +27 -9
  91. package/koni/api/tokens/wasm/index.js +5 -4
  92. package/koni/api/tokens/wasm/utils.d.ts +6 -0
  93. package/koni/api/tokens/wasm/utils.js +54 -0
  94. package/koni/api/xcm/polkadotXcm.js +2 -2
  95. package/koni/api/xcm/utils.d.ts +5 -6
  96. package/koni/api/xcm/utils.js +15 -10
  97. package/koni/api/xcm/xTokens.js +2 -2
  98. package/koni/api/xcm/xcmPallet.js +10 -9
  99. package/koni/background/cron.d.ts +6 -1
  100. package/koni/background/cron.js +172 -62
  101. package/koni/background/handlers/Extension.d.ts +9 -3
  102. package/koni/background/handlers/Extension.js +306 -126
  103. package/koni/background/handlers/State.d.ts +5 -6
  104. package/koni/background/handlers/State.js +51 -34
  105. package/koni/background/handlers/Tabs.js +50 -17
  106. package/koni/background/subscription.d.ts +2 -0
  107. package/koni/background/subscription.js +51 -29
  108. package/package.json +29 -14
  109. package/packageInfo.js +1 -1
  110. package/services/base/types.d.ts +34 -0
  111. package/services/base/types.js +15 -0
  112. package/services/chain-service/handler/SubstrateChainHandler.js +14 -9
  113. package/services/chain-service/helper/psp22_abi.json +1041 -881
  114. package/services/chain-service/helper/psp34_abi.json +2963 -1807
  115. package/services/chain-service/index.d.ts +5 -2
  116. package/services/chain-service/index.js +68 -45
  117. package/services/chain-service/types.d.ts +1 -0
  118. package/services/event-service/index.js +5 -1
  119. package/services/event-service/types.d.ts +5 -9
  120. package/services/event-service/types.js +4 -1
  121. package/services/history-service/index.d.ts +28 -7
  122. package/services/history-service/index.js +101 -50
  123. package/services/history-service/subsquid-multi-chain-history.js +16 -12
  124. package/services/keyring-service/index.d.ts +4 -2
  125. package/services/keyring-service/index.js +11 -13
  126. package/services/migration-service/scripts/MigrateImportedToken.js +2 -1
  127. package/services/price-service/coingecko.js +0 -1
  128. package/services/price-service/index.d.ts +22 -1
  129. package/services/price-service/index.js +71 -24
  130. package/services/request-service/handler/AuthRequestHandler.d.ts +3 -1
  131. package/services/request-service/handler/AuthRequestHandler.js +13 -7
  132. package/services/request-service/handler/EvmRequestHandler.js +8 -12
  133. package/services/request-service/index.d.ts +3 -1
  134. package/services/request-service/index.js +14 -5
  135. package/services/storage-service/DatabaseService.d.ts +2 -0
  136. package/services/storage-service/DatabaseService.js +66 -34
  137. package/services/storage-service/db-stores/Nft.d.ts +2 -2
  138. package/services/storage-service/db-stores/Nft.js +7 -14
  139. package/services/storage-service/db-stores/Transaction.d.ts +2 -0
  140. package/services/storage-service/db-stores/Transaction.js +6 -10
  141. package/services/transaction-service/event-parser/index.js +21 -49
  142. package/services/transaction-service/index.d.ts +2 -0
  143. package/services/transaction-service/index.js +86 -32
  144. package/services/transaction-service/types.d.ts +2 -0
  145. package/services/transaction-service/utils.js +10 -8
  146. package/utils/address.d.ts +3 -0
  147. package/utils/address.js +8 -1
  148. package/utils/index.d.ts +2 -2
  149. package/utils/index.js +7 -13
  150. package/utils/promise.d.ts +6 -0
  151. package/utils/promise.js +20 -0
@@ -6,6 +6,7 @@ import KoniDatabase from '@subwallet/extension-base/services/storage-service/dat
6
6
  import { AssetStore, BalanceStore, ChainStore, CrowdloanStore, MigrationStore, NftCollectionStore, NftStore, PriceStore, StakingStore, TransactionStore } from '@subwallet/extension-base/services/storage-service/db-stores';
7
7
  import ChainStakingMetadataStore from '@subwallet/extension-base/services/storage-service/db-stores/ChainStakingMetadata';
8
8
  import NominatorMetadataStore from '@subwallet/extension-base/services/storage-service/db-stores/NominatorMetadata';
9
+ import { reformatAddress } from '@subwallet/extension-base/utils';
9
10
  import { logger as createLogger } from '@polkadot/util';
10
11
  export default class DatabaseService {
11
12
  // TODO: might remove this
@@ -47,7 +48,8 @@ export default class DatabaseService {
47
48
  }
48
49
  async updateBalanceStore(address, item) {
49
50
  if (item.state === APIItemState.READY) {
50
- this.logger.log(`Updating balance for [${item.tokenSlug}]`);
51
+ // this.logger.log(`Updating balance for [${item.tokenSlug}]`);
52
+
51
53
  return this.stores.balance.upsert({
52
54
  address,
53
55
  ...item
@@ -62,14 +64,16 @@ export default class DatabaseService {
62
64
  // Crowdloan
63
65
  async updateCrowdloanStore(chain, address, item) {
64
66
  if (item.state === APIItemState.READY && item.contribute !== '0') {
65
- this.logger.log(`Updating crowdloan for [${chain}]`);
67
+ // this.logger.log(`Updating crowdloan for [${chain}]`);
68
+
66
69
  return this.stores.crowdloan.upsert({
67
70
  chain,
68
71
  address,
69
72
  ...item
70
73
  });
71
74
  } else {
72
- this.logger.debug(`Removing crowdloan for [${chain}]`);
75
+ // this.logger.debug(`Removing crowdloan for [${chain}]`);
76
+
73
77
  return this.stores.crowdloan.deleteByChainAndAddress(chain, address);
74
78
  }
75
79
  }
@@ -77,22 +81,23 @@ export default class DatabaseService {
77
81
  // Staking
78
82
  async updateStaking(chain, address, item) {
79
83
  if (item.state === APIItemState.READY) {
80
- this.logger.log(`Updating staking for [${chain}]`);
84
+ // this.logger.log(`Updating staking for [${chain}]`);
85
+
81
86
  return this.stores.staking.upsert(item);
82
87
  }
83
88
  }
84
89
  async getStakings(addresses, chains) {
85
- const stakings = await this.stores.staking.getStakings(addresses, chains);
86
- this.logger.log('Get Stakings: ', stakings);
87
- return stakings;
90
+ // this.logger.log('Get Stakings: ', stakings);
91
+
92
+ return this.stores.staking.getStakings(addresses, chains);
88
93
  }
89
94
  async getStakingsByChains(chains) {
90
95
  return this.stores.staking.getStakingsByChains(chains);
91
96
  }
92
97
  async getPooledStakings(addresses, chainHashes) {
93
- const stakings = await this.stores.staking.getPooledStakings(addresses, chainHashes);
94
- this.logger.log('Get Pooled Stakings: ', stakings);
95
- return stakings;
98
+ // this.logger.log('Get Pooled Stakings: ', stakings);
99
+
100
+ return this.stores.staking.getPooledStakings(addresses, chainHashes);
96
101
  }
97
102
  subscribeStaking(addresses, chainList, callback) {
98
103
  this.stakingSubscription && this.stakingSubscription.unsubscribe();
@@ -114,18 +119,28 @@ export default class DatabaseService {
114
119
 
115
120
  // Transaction histories
116
121
  async getHistories(query) {
117
- const histories = await this.stores.transaction.queryHistory(query);
118
- this.logger.log('Get histories: ', histories);
119
- return histories;
122
+ return this.stores.transaction.queryHistory(query);
120
123
  }
121
124
  async upsertHistory(histories) {
122
- this.logger.log('Updating transaction histories');
123
- return this.stores.transaction.bulkUpsert(histories);
125
+ // this.logger.log('Updating transaction histories');
126
+ const cleanedHistory = histories.filter(x => x && x.address && x.chain && x.extrinsicHash);
127
+ return this.stores.transaction.bulkUpsert(cleanedHistory);
128
+ }
129
+ async updateHistoryByNewExtrinsicHash(extrinsicHash, updateData) {
130
+ // this.logger.log('Updating transaction histories');
131
+ const canUpdate = updateData && extrinsicHash;
132
+ if (!canUpdate) {
133
+ return;
134
+ }
135
+ return this.stores.transaction.updateWithQuery({
136
+ extrinsicHash
137
+ }, updateData);
124
138
  }
125
139
 
126
140
  // NFT Collection
127
141
  async addNftCollection(collection) {
128
- this.logger.log(`Updating NFT collection for [${collection.chain}]`);
142
+ // this.logger.log(`Updating NFT collection for [${collection.chain}]`);
143
+
129
144
  return this.stores.nftCollection.upsert(collection);
130
145
  }
131
146
  async deleteNftCollection(chain, collectionId) {
@@ -144,13 +159,22 @@ export default class DatabaseService {
144
159
  });
145
160
  return this.nftSubscription;
146
161
  }
162
+ async cleanUpNft(chain, owner, collectionIds, nftIds, ownNothing) {
163
+ if (ownNothing) {
164
+ return this.stores.nft.deleteNftsByChainAndOwner(chain, reformatAddress(owner, 42));
165
+ }
166
+ const result = await this.stores.nft.cleanUpNfts(chain, reformatAddress(owner, 42), collectionIds, nftIds);
167
+ result > 0 && console.debug(`Cleaned up ${result} NFTs on chain ${chain} for owner ${reformatAddress(owner, 42)}`, collectionIds, nftIds);
168
+ return result;
169
+ }
147
170
  async getNft(addresses, chainHashes) {
148
- const nfts = await this.stores.nft.getNft(addresses, chainHashes);
149
- this.logger.log('Get NFTs: ', nfts);
150
- return nfts;
171
+ // this.logger.log('Get NFTs: ', nfts);
172
+
173
+ return this.stores.nft.getNft(addresses, chainHashes);
151
174
  }
152
175
  async addNft(address, nft) {
153
- this.logger.log(`Updating NFT for [${nft.chain}]`);
176
+ // this.logger.log(`Updating NFT for [${nft.chain}]`);
177
+
154
178
  return this.stores.nft.upsert({
155
179
  ...nft,
156
180
  address
@@ -160,47 +184,54 @@ export default class DatabaseService {
160
184
  return this.stores.nft.deleteNftItem(chain, addresses, nftItem);
161
185
  }
162
186
  removeNfts(chain, address, collectionId, nftIds) {
163
- this.logger.log(`Remove NFTs [${nftIds.join(', ')}]`);
187
+ // this.logger.log(`Remove NFTs [${nftIds.join(', ')}]`);
188
+
164
189
  return this.stores.nft.removeNfts(chain, address, collectionId, nftIds);
165
190
  }
166
191
 
167
192
  // Chain
168
193
  async updateChainStore(item) {
169
- this.logger.log(`Updating storageInfo for chain [${item.slug}]`);
194
+ // this.logger.log(`Updating storageInfo for chain [${item.slug}]`);
195
+
170
196
  return this.stores.chain.upsert(item);
171
197
  }
172
198
  async bulkUpdateChainStore(data) {
173
- this.logger.log('Bulk updating ChainStore');
199
+ // this.logger.log('Bulk updating ChainStore');
200
+
174
201
  return this.stores.chain.bulkUpsert(data);
175
202
  }
176
203
  async removeFromChainStore(chains) {
177
- this.logger.log('Bulk removing ChainStore');
204
+ // this.logger.log('Bulk removing ChainStore');
205
+
178
206
  return this.stores.chain.removeChains(chains);
179
207
  }
180
208
  async getAllChainStore() {
181
- const allChains = await this.stores.chain.getAll();
182
- this.logger.log('Get all chains: ', allChains);
183
- return allChains;
209
+ // this.logger.log('Get all chains: ', allChains);
210
+
211
+ return this.stores.chain.getAll();
184
212
  }
185
213
 
186
214
  // Asset
187
215
  async updateAssetStore(item) {
188
- this.logger.log(`Updating storageInfo for chainAsset [${item.originChain}]`);
216
+ // this.logger.log(`Updating storageInfo for chainAsset [${item.originChain}]`);
217
+
189
218
  return this.stores.asset.upsert(item);
190
219
  }
191
220
  async getAllAssetStore() {
192
- const allAssets = await this.stores.asset.getAll();
193
- this.logger.log('Get all stored assets: ', allAssets);
194
- return allAssets;
221
+ // this.logger.log('Get all stored assets: ', allAssets);
222
+
223
+ return this.stores.asset.getAll();
195
224
  }
196
225
  async removeFromAssetStore(items) {
197
- this.logger.log('Bulk removing AssetStore');
226
+ // this.logger.log('Bulk removing AssetStore');
227
+
198
228
  return this.stores.asset.removeAssets(items);
199
229
  }
200
230
 
201
231
  // Staking
202
232
  async updateChainStakingMetadata(item) {
203
- this.logger.log('Update ChainStakingMetadata: ', item.chain);
233
+ // this.logger.log('Update ChainStakingMetadata: ', item.chain);
234
+
204
235
  return this.stores.chainStakingMetadata.upsert(item);
205
236
  }
206
237
  async getChainStakingMetadata() {
@@ -210,7 +241,8 @@ export default class DatabaseService {
210
241
  return this.stores.chainStakingMetadata.getByChainAndType(chain, type);
211
242
  }
212
243
  async updateNominatorMetadata(item) {
213
- this.logger.log('Update NominatorMetadata: ', item.address, item.chain);
244
+ // this.logger.log('Update NominatorMetadata: ', item.address, item.chain);
245
+
214
246
  return this.stores.nominatorMetadata.upsert(item);
215
247
  }
216
248
  async getNominatorMetadata() {
@@ -4,8 +4,8 @@ import { INft } from '../databases';
4
4
  export default class NftStore extends BaseStoreWithAddressAndChain<INft> {
5
5
  getNft(addresses: string[], chainList?: string[]): import("dexie").PromiseExtended<INft[]>;
6
6
  subscribeNft(addresses: string[], chainList?: string[]): import("dexie").Observable<INft[]>;
7
- deleteRemovedNftsFromCollection(chainHash: string, address: string, collection?: string, nftIds?: string[]): void | import("dexie").PromiseExtended<number>;
8
- deleteNftsFromRemovedCollection(chain: string, address: string, collectionIds: string[]): import("dexie").Collection<INft, unknown>;
7
+ cleanUpNfts(chain: string, address: string, collectionIds: string[], nftIds: string[]): import("dexie").PromiseExtended<number>;
8
+ deleteNftsByChainAndOwner(chain: string, address: string): import("dexie").PromiseExtended<number>;
9
9
  deleteNftByAddress(addresses: string[]): import("dexie").PromiseExtended<number>;
10
10
  deleteNftItem(chain: string, addresses: string[], nftItem: NftItem): import("dexie").PromiseExtended<number>;
11
11
  deleteNftsByCollection(chain: string, collectionId: string): import("dexie").PromiseExtended<number>;
@@ -15,24 +15,17 @@ export default class NftStore extends BaseStoreWithAddressAndChain {
15
15
  subscribeNft(addresses, chainList = []) {
16
16
  return liveQuery(() => this.getNft(addresses, chainList));
17
17
  }
18
- deleteRemovedNftsFromCollection(chainHash, address, collection, nftIds = []) {
19
- const conditions = {
20
- chainHash,
21
- address
22
- };
23
- if (!collection && nftIds && nftIds.length) {
24
- return this.logger.warn('Missing collection id');
25
- }
26
- if (collection) {
27
- conditions.collectionId = collection;
28
- }
29
- return this.table.where(conditions).and(item => !nftIds.some(nft => nft === item.id)).delete();
18
+ cleanUpNfts(chain, address, collectionIds, nftIds) {
19
+ return this.table.where({
20
+ address,
21
+ chain
22
+ }).and(nft => !collectionIds.includes(nft.collectionId) || collectionIds.includes(nft.collectionId) && !nftIds.includes(nft.id)).delete();
30
23
  }
31
- deleteNftsFromRemovedCollection(chain, address, collectionIds) {
24
+ deleteNftsByChainAndOwner(chain, address) {
32
25
  return this.table.where({
33
26
  address,
34
27
  chain
35
- }).and(nft => !collectionIds.some(item => item === nft.collectionId));
28
+ }).delete();
36
29
  }
37
30
  deleteNftByAddress(addresses) {
38
31
  return this.table.where('address').anyOfIgnoreCase(addresses).delete();
@@ -4,9 +4,11 @@ export interface HistoryQuery {
4
4
  chain?: string;
5
5
  address?: string;
6
6
  extrinsicHash?: string;
7
+ transactionId?: string;
7
8
  }
8
9
  export default class TransactionStore extends BaseStoreWithAddressAndChain<ITransactionHistoryItem> {
9
10
  getHistoryByAddressAsObject(address: string): Promise<ITransactionHistoryItem[]>;
10
11
  queryHistory(query?: HistoryQuery): Promise<ITransactionHistoryItem[]>;
11
12
  bulkUpsert(records: ITransactionHistoryItem[]): Promise<unknown>;
13
+ updateWithQuery(query: HistoryQuery, update: Partial<ITransactionHistoryItem>): Promise<unknown>;
12
14
  }
@@ -29,16 +29,12 @@ export default class TransactionStore extends BaseStoreWithAddressAndChain {
29
29
  }
30
30
  async bulkUpsert(records) {
31
31
  await this.table.bulkPut(records);
32
-
33
- // await Promise.all(records.map((record) => {
34
- // return this.table.where({
35
- // chain: record.chain,
36
- // address: record.address,
37
- // extrinsicHash: record.extrinsicHash
38
- // }).filter((item) => (item.origin === 'app' && record.origin !== 'app'))
39
- // .delete();
40
- // }));
41
-
32
+ return true;
33
+ }
34
+ async updateWithQuery(query, update) {
35
+ await this.table.where(query).modify(record => {
36
+ return Object.assign(record, update);
37
+ });
42
38
  return true;
43
39
  }
44
40
  }
@@ -1,45 +1,30 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { _getAssetDecimals, _getChainNativeTokenBasicInfo, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
4
+ import { _getAssetDecimals, _getChainNativeTokenBasicInfo } from '@subwallet/extension-base/services/chain-service/utils';
5
5
  export function parseXcmEventLogs(historyItem, eventLogs, chain, sendingTokenInfo, chainInfo) {
6
- let isFeeUseMainTokenSymbol = true;
7
6
  for (let index = 0; index < eventLogs.length; index++) {
8
7
  const record = eventLogs[index];
9
- if (['karura', 'acala', 'acala_testnet'].includes(chain) && sendingTokenInfo && !_isNativeToken(sendingTokenInfo)) {
10
- if (record.event.section === 'currencies' && record.event.method.toLowerCase() === 'transferred') {
11
- if (index === 0) {
12
- var _record$event$data$;
13
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
14
- historyItem.fee = {
15
- value: ((_record$event$data$ = record.event.data[3]) === null || _record$event$data$ === void 0 ? void 0 : _record$event$data$.toString()) || '0',
16
- symbol: sendingTokenInfo.symbol,
17
- decimals: _getAssetDecimals(sendingTokenInfo)
18
- };
19
- isFeeUseMainTokenSymbol = false;
20
- }
21
- }
22
- }
23
8
  const {
24
9
  decimals: nativeDecimals,
25
10
  symbol: nativeSymbol
26
11
  } = _getChainNativeTokenBasicInfo(chainInfo);
27
- if (isFeeUseMainTokenSymbol && record.event.section === 'balances' && record.event.method.toLowerCase() === 'withdraw') {
28
- var _record$event$data$2;
29
- if ((_record$event$data$2 = record.event.data[1]) !== null && _record$event$data$2 !== void 0 && _record$event$data$2.toString()) {
30
- var _record$event$data$3;
12
+ if (record.event.section === 'balances' && record.event.method.toLowerCase() === 'withdraw') {
13
+ var _record$event$data$;
14
+ if ((_record$event$data$ = record.event.data[1]) !== null && _record$event$data$ !== void 0 && _record$event$data$.toString()) {
15
+ var _record$event$data$2;
31
16
  historyItem.fee = {
32
- value: (_record$event$data$3 = record.event.data[1]) === null || _record$event$data$3 === void 0 ? void 0 : _record$event$data$3.toString(),
17
+ value: (_record$event$data$2 = record.event.data[1]) === null || _record$event$data$2 === void 0 ? void 0 : _record$event$data$2.toString(),
33
18
  symbol: nativeSymbol,
34
19
  decimals: nativeDecimals
35
20
  };
36
21
  }
37
- } else if (isFeeUseMainTokenSymbol && record.event.section === 'tokens' && record.event.method.toLowerCase() === 'withdrawn') {
38
- var _record$event$data$4;
39
- if ((_record$event$data$4 = record.event.data[2]) !== null && _record$event$data$4 !== void 0 && _record$event$data$4.toString()) {
40
- var _record$event$data$5;
22
+ } else if (record.event.section === 'tokens' && record.event.method.toLowerCase() === 'withdrawn') {
23
+ var _record$event$data$3;
24
+ if (!historyItem.fee && (_record$event$data$3 = record.event.data[2]) !== null && _record$event$data$3 !== void 0 && _record$event$data$3.toString()) {
25
+ var _record$event$data$4;
41
26
  historyItem.fee = {
42
- value: (_record$event$data$5 = record.event.data[2]) === null || _record$event$data$5 === void 0 ? void 0 : _record$event$data$5.toString(),
27
+ value: (_record$event$data$4 = record.event.data[2]) === null || _record$event$data$4 === void 0 ? void 0 : _record$event$data$4.toString(),
43
28
  symbol: nativeSymbol,
44
29
  decimals: nativeDecimals
45
30
  };
@@ -48,28 +33,15 @@ export function parseXcmEventLogs(historyItem, eventLogs, chain, sendingTokenInf
48
33
  }
49
34
  }
50
35
  export function parseTransferEventLogs(historyItem, eventLogs, chain, sendingTokenInfo, chainInfo) {
51
- let isFeeUseMainTokenSymbol = true;
52
36
  for (let index = 0; index < eventLogs.length; index++) {
53
37
  const record = eventLogs[index];
54
- if (['karura', 'acala', 'acala_testnet'].includes(chain) && !_isNativeToken(sendingTokenInfo)) {
55
- if (record.event.section === 'currencies' && record.event.method.toLowerCase() === 'transferred') {
56
- if (index === 0) {
57
- var _record$event$data$6;
58
- historyItem.fee = {
59
- value: ((_record$event$data$6 = record.event.data[3]) === null || _record$event$data$6 === void 0 ? void 0 : _record$event$data$6.toString()) || '0',
60
- symbol: sendingTokenInfo.symbol,
61
- decimals: _getAssetDecimals(sendingTokenInfo)
62
- };
63
- isFeeUseMainTokenSymbol = false;
64
- }
65
- }
66
- } else if (['genshiro_testnet', 'genshiro', 'equilibrium_parachain'].includes(chain) && sendingTokenInfo) {
38
+ if (['genshiro_testnet', 'genshiro', 'equilibrium_parachain'].includes(chain) && sendingTokenInfo) {
67
39
  if (record.event.section === 'transactionPayment' && record.event.method.toLowerCase() === 'transactionfeepaid') {
68
- var _record$event$data$7;
69
- if ((_record$event$data$7 = record.event.data[1]) !== null && _record$event$data$7 !== void 0 && _record$event$data$7.toString()) {
70
- var _record$event$data$8;
40
+ var _record$event$data$5;
41
+ if ((_record$event$data$5 = record.event.data[1]) !== null && _record$event$data$5 !== void 0 && _record$event$data$5.toString()) {
42
+ var _record$event$data$6;
71
43
  historyItem.fee = {
72
- value: ((_record$event$data$8 = record.event.data[1]) === null || _record$event$data$8 === void 0 ? void 0 : _record$event$data$8.toString()) || '0',
44
+ value: ((_record$event$data$6 = record.event.data[1]) === null || _record$event$data$6 === void 0 ? void 0 : _record$event$data$6.toString()) || '0',
73
45
  symbol: sendingTokenInfo.symbol,
74
46
  decimals: _getAssetDecimals(sendingTokenInfo)
75
47
  };
@@ -80,13 +52,13 @@ export function parseTransferEventLogs(historyItem, eventLogs, chain, sendingTok
80
52
  decimals: nativeDecimals,
81
53
  symbol: nativeSymbol
82
54
  } = _getChainNativeTokenBasicInfo(chainInfo);
83
- if (isFeeUseMainTokenSymbol && record.event.section === 'balances' && record.event.method.toLowerCase() === 'withdraw') {
84
- var _record$event$data$9;
85
- if ((_record$event$data$9 = record.event.data[1]) !== null && _record$event$data$9 !== void 0 && _record$event$data$9.toString()) {
86
- var _record$event$data$10;
55
+ if (record.event.section === 'balances' && record.event.method.toLowerCase() === 'withdraw') {
56
+ var _record$event$data$7;
57
+ if ((_record$event$data$7 = record.event.data[1]) !== null && _record$event$data$7 !== void 0 && _record$event$data$7.toString()) {
58
+ var _record$event$data$8;
87
59
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
88
60
  historyItem.fee = {
89
- value: ((_record$event$data$10 = record.event.data[1]) === null || _record$event$data$10 === void 0 ? void 0 : _record$event$data$10.toString()) || '0',
61
+ value: ((_record$event$data$8 = record.event.data[1]) === null || _record$event$data$8 === void 0 ? void 0 : _record$event$data$8.toString()) || '0',
90
62
  symbol: nativeSymbol,
91
63
  decimals: nativeDecimals
92
64
  };
@@ -36,6 +36,8 @@ export default class TransactionService {
36
36
  private updateTransaction;
37
37
  private getTransactionLink;
38
38
  private transactionToHistories;
39
+ private onSigned;
40
+ private onSend;
39
41
  private onHasTransactionHash;
40
42
  private handlePostProcessing;
41
43
  private onSuccess;
@@ -37,7 +37,7 @@ export default class TransactionService {
37
37
  return Object.values(this.transactions);
38
38
  }
39
39
  get processingTransactions() {
40
- return this.allTransactions.filter(t => t.status === ExtrinsicStatus.PENDING || t.status === ExtrinsicStatus.PROCESSING);
40
+ return this.allTransactions.filter(t => t.status === ExtrinsicStatus.QUEUED || t.status === ExtrinsicStatus.PROCESSING);
41
41
  }
42
42
  getTransaction(id) {
43
43
  return this.transactions[id];
@@ -157,6 +157,7 @@ export default class TransactionService {
157
157
  }
158
158
  fillTransactionDefaultInfo(transaction) {
159
159
  const isInternal = !transaction.url;
160
+ const transactionId = getTransactionId(transaction.chainType, transaction.chain, isInternal);
160
161
  return {
161
162
  ...transaction,
162
163
  createdAt: new Date(),
@@ -164,10 +165,10 @@ export default class TransactionService {
164
165
  errors: transaction.errors || [],
165
166
  warnings: transaction.warnings || [],
166
167
  url: transaction.url || EXTENSION_REQUEST_URL,
167
- status: ExtrinsicStatus.PENDING,
168
+ status: ExtrinsicStatus.QUEUED,
168
169
  isInternal,
169
- id: getTransactionId(transaction.chainType, transaction.chain, isInternal),
170
- extrinsicHash: ''
170
+ id: transactionId,
171
+ extrinsicHash: transactionId
171
172
  };
172
173
  }
173
174
  async addTransaction(inputTransaction) {
@@ -180,9 +181,6 @@ export default class TransactionService {
180
181
  this.transactionSubject.next({
181
182
  ...transactions
182
183
  });
183
- console.log(transaction);
184
-
185
- // Send transaction
186
184
  return await this.sendTransaction(transaction);
187
185
  }
188
186
  generateBeforeHandleResponseErrors(errors) {
@@ -209,7 +207,8 @@ export default class TransactionService {
209
207
  validatedTransaction.warnings = [];
210
208
  const emitter = await this.addTransaction(validatedTransaction);
211
209
  await new Promise(resolve => {
212
- emitter.on('extrinsicHash', data => {
210
+ emitter.on('signed', data => {
211
+ validatedTransaction.id = data.id;
213
212
  validatedTransaction.extrinsicHash = data.extrinsicHash;
214
213
  resolve();
215
214
  });
@@ -225,6 +224,12 @@ export default class TransactionService {
225
224
  async sendTransaction(transaction) {
226
225
  // Send Transaction
227
226
  const emitter = transaction.chainType === 'substrate' ? this.signAndSendSubstrateTransaction(transaction) : await this.signAndSendEvmTransaction(transaction);
227
+ emitter.on('signed', data => {
228
+ this.onSigned(data);
229
+ });
230
+ emitter.on('send', data => {
231
+ this.onSend(data);
232
+ });
228
233
  emitter.on('extrinsicHash', data => {
229
234
  this.onHasTransactionHash(data);
230
235
  });
@@ -277,7 +282,8 @@ export default class TransactionService {
277
282
  to: '',
278
283
  chainType: transaction.chainType,
279
284
  address: transaction.address,
280
- status: ExtrinsicStatus.PROCESSING,
285
+ status: transaction.status,
286
+ transactionId: transaction.id,
281
287
  extrinsicHash: transaction.extrinsicHash,
282
288
  time: transaction.createdAt.getTime(),
283
289
  fee: transaction.estimateFee,
@@ -420,18 +426,24 @@ export default class TransactionService {
420
426
  break;
421
427
  }
422
428
  case ExtrinsicType.EVM_EXECUTE:
423
- // Todo: Update historyItem.to
424
- break;
429
+ {
430
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
431
+ const data = parseTransactionData(transaction.data);
432
+
433
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
434
+ historyItem.to = (data === null || data === void 0 ? void 0 : data.to) || '';
435
+ break;
436
+ }
425
437
  case ExtrinsicType.UNKNOWN:
426
438
  break;
427
439
  }
428
440
  try {
429
441
  // Return one more history record if transaction send to account in the wallets
430
- const toAccount = (historyItem === null || historyItem === void 0 ? void 0 : historyItem.to) && keyring.getAccount(historyItem.to);
442
+ const toAccount = (historyItem === null || historyItem === void 0 ? void 0 : historyItem.to) && keyring.getPair(historyItem.to);
431
443
  if (toAccount) {
432
444
  return [historyItem, {
433
445
  ...historyItem,
434
- address: historyItem.to,
446
+ address: toAccount.address,
435
447
  direction: TransactionDirection.RECEIVED
436
448
  }];
437
449
  }
@@ -440,34 +452,62 @@ export default class TransactionService {
440
452
  }
441
453
  return [historyItem];
442
454
  }
455
+ onSigned({
456
+ id
457
+ }) {
458
+ console.log(`Transaction "${id}" is signed`);
459
+ }
460
+ onSend({
461
+ id
462
+ }) {
463
+ // Update transaction status
464
+ this.updateTransaction(id, {
465
+ status: ExtrinsicStatus.SUBMITTING
466
+ });
467
+
468
+ // Create Input History Transaction History
469
+ this.historyService.insertHistories(this.transactionToHistories(id)).catch(console.error);
470
+ console.log(`Transaction "${id}" is sent`);
471
+ }
443
472
  onHasTransactionHash({
444
- eventLogs,
445
473
  extrinsicHash,
446
474
  id
447
475
  }) {
448
476
  // Write processing transaction history
449
- this.updateTransaction(id, {
477
+ const updateData = {
450
478
  extrinsicHash,
451
479
  status: ExtrinsicStatus.PROCESSING
452
- });
453
- this.historyService.insertHistories(this.transactionToHistories(id, eventLogs)).catch(console.error);
480
+ };
481
+ this.updateTransaction(id, updateData);
482
+
483
+ // In this case transaction id is the same as extrinsic hash and will change after below update
484
+ this.historyService.updateHistoryByExtrinsicHash(id, updateData).catch(console.error);
454
485
  console.log(`Transaction "${id}" is submitted with hash ${extrinsicHash || ''}`);
455
486
  }
456
487
  handlePostProcessing(id) {
457
488
  // must be done after success/failure to make sure the transaction is finalized
458
489
  const transaction = this.getTransaction(id);
459
- switch (transaction.extrinsicType) {
460
- case ExtrinsicType.SEND_NFT:
461
- {
462
- const inputData = parseTransactionData(transaction.data);
463
- const sender = keyring.getAccount(inputData.senderAddress);
464
- const recipient = keyring.getAccount(inputData.recipientAddress);
465
- sender && this.databaseService.handleNftTransfer(transaction.chain, [sender.address, ALL_ACCOUNT_KEY], inputData.nftItem).catch(console.error);
466
- recipient && this.databaseService.addNft(recipient.address, {
467
- ...inputData.nftItem,
468
- owner: recipient.address
469
- }).catch(console.error);
470
- }
490
+ if (transaction.extrinsicType === ExtrinsicType.SEND_NFT) {
491
+ const inputData = parseTransactionData(transaction.data);
492
+ try {
493
+ const sender = keyring.getPair(inputData.senderAddress);
494
+ sender && this.databaseService.handleNftTransfer(transaction.chain, [sender.address, ALL_ACCOUNT_KEY], inputData.nftItem).then(() => {
495
+ this.eventService.emit('transaction.transferNft', undefined);
496
+ }).catch(console.error);
497
+ } catch (e) {
498
+ console.error(e);
499
+ }
500
+ try {
501
+ const recipient = keyring.getPair(inputData.recipientAddress);
502
+ recipient && this.databaseService.addNft(recipient.address, {
503
+ ...inputData.nftItem,
504
+ owner: recipient.address
505
+ }).catch(console.error);
506
+ } catch (e) {
507
+ console.error(e);
508
+ }
509
+ } else if ([ExtrinsicType.STAKING_BOND, ExtrinsicType.STAKING_UNBOND, ExtrinsicType.STAKING_WITHDRAW, ExtrinsicType.STAKING_CANCEL_UNSTAKE, ExtrinsicType.STAKING_CLAIM_REWARD, ExtrinsicType.STAKING_JOIN_POOL, ExtrinsicType.STAKING_POOL_WITHDRAW, ExtrinsicType.STAKING_LEAVE_POOL].includes(transaction.extrinsicType)) {
510
+ this.eventService.emit('transaction.submitStaking', transaction.chain);
471
511
  }
472
512
  }
473
513
  onSuccess({
@@ -505,16 +545,17 @@ export default class TransactionService {
505
545
  id
506
546
  }) {
507
547
  const transaction = this.getTransaction(id);
548
+ const nextStatus = ExtrinsicStatus.FAIL;
508
549
  if (transaction) {
509
550
  this.updateTransaction(id, {
510
- status: ExtrinsicStatus.FAIL,
551
+ status: nextStatus,
511
552
  errors
512
553
  });
513
554
  console.log('Transaction failed', id, transaction.extrinsicHash);
514
555
 
515
556
  // Write failed transaction history
516
557
  this.historyService.updateHistories(transaction.chain, transaction.extrinsicHash, {
517
- status: ExtrinsicStatus.FAIL,
558
+ status: nextStatus,
518
559
  blockNumber: blockNumber || 0,
519
560
  blockHash: blockHash || ''
520
561
  }).catch(console.error);
@@ -576,6 +617,9 @@ export default class TransactionService {
576
617
  payload.isToContract = isToContract;
577
618
  payload.parseData = isToContract ? payload.data ? (await parseContractInput(payload.data || '', payload.to || '', chainInfo)).result : '' : payload.data || '';
578
619
  }
620
+ if ('data' in payload && payload.data === undefined) {
621
+ delete payload.data;
622
+ }
579
623
 
580
624
  // Set unique nonce to avoid transaction errors
581
625
  if (!payload.nonce) {
@@ -631,6 +675,12 @@ export default class TransactionService {
631
675
  }
632
676
  signedTransaction = signed;
633
677
  }
678
+
679
+ // Emit signed event
680
+ emitter.emit('signed', eventData);
681
+
682
+ // Send transaction
683
+ emitter.emit('send', eventData); // This event is needed after sending transaction with queue
634
684
  signedTransaction && web3Api.eth.sendSignedTransaction(signedTransaction).once('transactionHash', hash => {
635
685
  eventData.extrinsicHash = hash;
636
686
  emitter.emit('extrinsicHash', eventData);
@@ -669,7 +719,6 @@ export default class TransactionService {
669
719
  errors: [],
670
720
  warnings: []
671
721
  };
672
- console.debug(address, transaction);
673
722
  transaction.signAsync(address, {
674
723
  signer: {
675
724
  signPayload: async payload => {
@@ -681,6 +730,11 @@ export default class TransactionService {
681
730
  }
682
731
  }
683
732
  }).then(rs => {
733
+ // Emit signed event
734
+ emitter.emit('signed', eventData);
735
+
736
+ // Send transaction
737
+ emitter.emit('send', eventData); // This event is needed after sending transaction with queue
684
738
  rs.send(txState => {
685
739
  // handle events, logs, history
686
740
  if (!txState || !txState.status) {
@@ -41,6 +41,8 @@ export interface TransactionEventResponse extends ValidateTransactionResponse {
41
41
  eventLogs?: EventRecord[];
42
42
  }
43
43
  export interface TransactionEventMap {
44
+ send: (response: TransactionEventResponse) => void;
45
+ signed: (response: TransactionEventResponse) => void;
44
46
  extrinsicHash: (response: TransactionEventResponse) => void;
45
47
  error: (response: TransactionEventResponse) => void;
46
48
  success: (response: TransactionEventResponse) => void;