@subwallet/extension-base 1.3.45-1 → 1.3.47-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 (128) hide show
  1. package/background/KoniTypes.d.ts +5 -0
  2. package/background/KoniTypes.js +5 -0
  3. package/background/types.d.ts +2 -0
  4. package/cjs/background/KoniTypes.js +7 -1
  5. package/cjs/core/logic-validation/request.js +55 -28
  6. package/cjs/core/utils.js +22 -0
  7. package/cjs/koni/api/nft/ordinal_nft/index.js +3 -2
  8. package/cjs/koni/background/handlers/Extension.js +84 -61
  9. package/cjs/koni/background/handlers/State.js +3 -0
  10. package/cjs/koni/background/handlers/Tabs.js +11 -3
  11. package/cjs/packageInfo.js +1 -1
  12. package/cjs/page/evm/index.js +64 -105
  13. package/cjs/page/index.js +5 -3
  14. package/cjs/page/substrate/Accounts.js +2 -1
  15. package/cjs/services/balance-service/helpers/subscribe/index.js +3 -76
  16. package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +8 -14
  17. package/cjs/services/buy-service/index.js +2 -0
  18. package/cjs/services/chain-service/index.js +3 -0
  19. package/cjs/services/chain-service/utils/index.js +34 -1
  20. package/cjs/services/chain-service/utils/patch.js +1 -1
  21. package/cjs/services/earning-service/constants/chains.js +2 -1
  22. package/cjs/services/earning-service/handlers/native-staking/amplitude.js +32 -0
  23. package/cjs/services/earning-service/handlers/native-staking/astar.js +18 -0
  24. package/cjs/services/earning-service/handlers/native-staking/base.js +40 -29
  25. package/cjs/services/earning-service/handlers/native-staking/dtao.js +5 -0
  26. package/cjs/services/earning-service/handlers/native-staking/mythos.js +28 -0
  27. package/cjs/services/earning-service/handlers/native-staking/para-chain.js +17 -0
  28. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +25 -2
  29. package/cjs/services/earning-service/handlers/native-staking/tao.js +5 -0
  30. package/cjs/services/earning-service/handlers/nomination-pool/index.js +6 -3
  31. package/cjs/services/earning-service/service.js +65 -22
  32. package/cjs/services/history-service/index.js +12 -7
  33. package/cjs/services/keyring-service/context/handlers/Json.js +2 -1
  34. package/cjs/services/keyring-service/context/handlers/Ledger.js +7 -2
  35. package/cjs/services/request-service/handler/AuthRequestHandler.js +30 -6
  36. package/cjs/services/subscan-service/index.js +35 -104
  37. package/cjs/services/transaction-service/utils.js +10 -1
  38. package/cjs/strategy/api-request-strategy/index.js +1 -0
  39. package/cjs/strategy/api-request-strategy/utils/index.js +2 -2
  40. package/cjs/strategy/api-request-strategy-v2/index.js +138 -0
  41. package/cjs/strategy/api-request-strategy-v2/types.js +1 -0
  42. package/cjs/types/account/info/keyring.js +1 -0
  43. package/cjs/utils/account/analyze.js +5 -2
  44. package/cjs/utils/account/common.js +93 -2
  45. package/cjs/utils/account/transform.js +10 -0
  46. package/cjs/utils/asset.js +9 -2
  47. package/cjs/utils/gear/combine.js +4 -3
  48. package/cjs/utils/gear/vft.js +104 -135
  49. package/cjs/utils/staticData/index.js +7 -2
  50. package/core/logic-validation/request.js +31 -4
  51. package/core/types.d.ts +3 -2
  52. package/core/utils.js +24 -2
  53. package/koni/api/nft/ordinal_nft/index.js +3 -2
  54. package/koni/background/handlers/Extension.js +31 -8
  55. package/koni/background/handlers/State.js +4 -1
  56. package/koni/background/handlers/Tabs.js +11 -4
  57. package/package.json +21 -9
  58. package/packageInfo.js +1 -1
  59. package/page/evm/index.d.ts +9 -18
  60. package/page/evm/index.js +62 -101
  61. package/page/index.js +5 -3
  62. package/page/substrate/Accounts.js +2 -1
  63. package/services/balance-service/helpers/subscribe/index.d.ts +1 -11
  64. package/services/balance-service/helpers/subscribe/index.js +3 -74
  65. package/services/balance-service/helpers/subscribe/substrate/index.js +8 -14
  66. package/services/buy-service/index.js +2 -0
  67. package/services/chain-service/index.d.ts +1 -0
  68. package/services/chain-service/index.js +3 -0
  69. package/services/chain-service/utils/index.d.ts +10 -2
  70. package/services/chain-service/utils/index.js +29 -2
  71. package/services/chain-service/utils/patch.js +1 -1
  72. package/services/earning-service/constants/chains.d.ts +1 -0
  73. package/services/earning-service/constants/chains.js +2 -1
  74. package/services/earning-service/handlers/native-staking/amplitude.d.ts +1 -0
  75. package/services/earning-service/handlers/native-staking/amplitude.js +32 -0
  76. package/services/earning-service/handlers/native-staking/astar.d.ts +1 -0
  77. package/services/earning-service/handlers/native-staking/astar.js +18 -0
  78. package/services/earning-service/handlers/native-staking/base.d.ts +2 -0
  79. package/services/earning-service/handlers/native-staking/base.js +40 -29
  80. package/services/earning-service/handlers/native-staking/dtao.d.ts +1 -0
  81. package/services/earning-service/handlers/native-staking/dtao.js +5 -0
  82. package/services/earning-service/handlers/native-staking/mythos.d.ts +1 -0
  83. package/services/earning-service/handlers/native-staking/mythos.js +28 -0
  84. package/services/earning-service/handlers/native-staking/para-chain.d.ts +1 -0
  85. package/services/earning-service/handlers/native-staking/para-chain.js +17 -0
  86. package/services/earning-service/handlers/native-staking/relay-chain.d.ts +1 -0
  87. package/services/earning-service/handlers/native-staking/relay-chain.js +25 -2
  88. package/services/earning-service/handlers/native-staking/tao.d.ts +1 -0
  89. package/services/earning-service/handlers/native-staking/tao.js +5 -0
  90. package/services/earning-service/handlers/nomination-pool/index.d.ts +1 -0
  91. package/services/earning-service/handlers/nomination-pool/index.js +6 -3
  92. package/services/earning-service/service.d.ts +3 -0
  93. package/services/earning-service/service.js +68 -25
  94. package/services/history-service/index.js +12 -7
  95. package/services/keyring-service/context/handlers/Json.js +2 -1
  96. package/services/keyring-service/context/handlers/Ledger.js +7 -2
  97. package/services/request-service/handler/AuthRequestHandler.d.ts +1 -0
  98. package/services/request-service/handler/AuthRequestHandler.js +30 -6
  99. package/services/request-service/types.d.ts +1 -0
  100. package/services/subscan-service/index.d.ts +13 -27
  101. package/services/subscan-service/index.js +26 -95
  102. package/services/transaction-service/utils.js +11 -2
  103. package/strategy/api-request-strategy/context/base.d.ts +2 -6
  104. package/strategy/api-request-strategy/index.js +1 -0
  105. package/strategy/api-request-strategy/types.d.ts +4 -2
  106. package/strategy/api-request-strategy/utils/index.js +2 -2
  107. package/strategy/api-request-strategy-v2/index.d.ts +22 -0
  108. package/strategy/api-request-strategy-v2/index.js +128 -0
  109. package/strategy/api-request-strategy-v2/types.d.ts +11 -0
  110. package/strategy/api-request-strategy-v2/types.js +1 -0
  111. package/types/account/action/subscribe.d.ts +3 -0
  112. package/types/account/info/keyring.d.ts +3 -0
  113. package/types/account/info/keyring.js +1 -0
  114. package/types/balance/transfer.d.ts +1 -0
  115. package/types/buy.d.ts +1 -1
  116. package/utils/account/analyze.js +5 -2
  117. package/utils/account/common.d.ts +13 -1
  118. package/utils/account/common.js +91 -2
  119. package/utils/account/transform.js +10 -0
  120. package/utils/asset.d.ts +2 -1
  121. package/utils/asset.js +7 -1
  122. package/utils/gear/combine.d.ts +2 -1
  123. package/utils/gear/combine.js +4 -4
  124. package/utils/gear/vft.d.ts +20 -9
  125. package/utils/gear/vft.js +104 -135
  126. package/utils/staticData/assetHubStaking.json +1 -0
  127. package/utils/staticData/index.d.ts +4 -1
  128. package/utils/staticData/index.js +5 -1
@@ -3,33 +3,32 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.VftService = exports.VFT = void 0;
7
- var _api = require("@gear-js/api");
6
+ exports.sailsCache = exports.VftService = exports.VFT = void 0;
8
7
  var _sailsJs = require("sails-js");
9
- var _types = require("@polkadot/types");
8
+ var _sailsJsParser = require("sails-js-parser");
10
9
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
11
10
  // SPDX-License-Identifier: Apache-2.0
12
11
 
13
12
  class VFT {
14
13
  constructor(api) {
15
14
  let programId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0x';
15
+ let sails = arguments.length > 2 ? arguments[2] : undefined;
16
16
  this.api = api;
17
17
  this.programId = programId;
18
- const types = {};
19
- this.registry = new _types.TypeRegistry();
20
- this.registry.setKnownTypes({
21
- types
22
- });
23
- this.registry.register(types);
18
+ this.sails = sails;
19
+ this.sails.setApi(api);
20
+ this.sails.setProgramId(programId);
24
21
  this.service = new VftService(this);
25
22
  }
26
23
  newCtorFromCode(code, name, symbol, decimals) {
27
- const builder = new _sailsJs.TransactionBuilder(this.api, this.registry, 'upload_program', ['New', name, symbol, decimals], '(String, String, String, u8)', 'String', code);
24
+ const ctor = this.sails.ctors.New;
25
+ const builder = ctor.fromCode(code, name, symbol, decimals);
28
26
  this.programId = builder.programId;
29
27
  return builder;
30
28
  }
31
29
  newCtorFromCodeId(codeId, name, symbol, decimals) {
32
- const builder = new _sailsJs.TransactionBuilder(this.api, this.registry, 'create_program', ['New', name, symbol, decimals], '(String, String, String, u8)', 'String', codeId);
30
+ const ctor = this.sails.ctors.New;
31
+ const builder = ctor.fromCodeId(codeId, name, symbol, decimals);
33
32
  this.programId = builder.programId;
34
33
  return builder;
35
34
  }
@@ -39,135 +38,105 @@ class VftService {
39
38
  constructor(_program) {
40
39
  this._program = _program;
41
40
  }
41
+ get functions() {
42
+ return this._program.sails.services.Vft.functions;
43
+ }
44
+ get queries() {
45
+ return this._program.sails.services.Vft.queries;
46
+ }
42
47
  approve(spender, value) {
43
- if (!this._program.programId) {
44
- throw new Error('Program ID is not set');
45
- }
46
- return new _sailsJs.TransactionBuilder(this._program.api, this._program.registry, 'send_message', ['Vft', 'Approve', spender, value], '(String, String, [u8;32], U256)', 'bool', this._program.programId);
48
+ return this.functions.Approve(spender, value);
47
49
  }
48
50
  transfer(to, value) {
49
- if (!this._program.programId) {
50
- throw new Error('Program ID is not set');
51
- }
52
- return new _sailsJs.TransactionBuilder(this._program.api, this._program.registry, 'send_message', ['Vft', 'Transfer', to, value], '(String, String, [u8;32], U256)', 'bool', this._program.programId);
51
+ return this.functions.Transfer(to, value);
53
52
  }
54
53
  transferFrom(from, to, value) {
55
- if (!this._program.programId) {
56
- throw new Error('Program ID is not set');
54
+ return this.functions.TransferFrom(from, to, value);
55
+ }
56
+ allowance(owner, spender, originAddress, value, atBlock) {
57
+ return this.queries.Allowance(originAddress, BigInt(value || 0), atBlock, owner, spender);
58
+ }
59
+ balanceOf(account, originAddress, value, atBlock) {
60
+ return this.queries.BalanceOf(originAddress, BigInt(value || 0), atBlock, account);
61
+ }
62
+ decimals(originAddress, value, atBlock) {
63
+ return this.queries.Decimals(originAddress, BigInt(value || 0), atBlock);
64
+ }
65
+ name(originAddress, value, atBlock) {
66
+ return this.queries.Name(originAddress, BigInt(value || 0), atBlock);
67
+ }
68
+ symbol(originAddress, value, atBlock) {
69
+ return this.queries.Symbol(originAddress, BigInt(value || 0), atBlock);
70
+ }
71
+ totalSupply(originAddress, value, atBlock) {
72
+ return this.queries.TotalSupply(originAddress, BigInt(value || 0), atBlock);
73
+ }
74
+ async subscribeToApprovalEvent(callback) {
75
+ return this._program.sails.services.Vft.events.Approval.subscribe(callback);
76
+ }
77
+ async subscribeToTransferEvent(callback) {
78
+ return this._program.sails.services.Vft.events.Transfer.subscribe(callback);
79
+ }
80
+ }
81
+
82
+ // Cache sai
83
+ exports.VftService = VftService;
84
+ const vftIdl = `
85
+ constructor {
86
+ New : (name: str, symbol: str, decimals: u8);
87
+ };
88
+
89
+ service Vft {
90
+ Approve : (spender: actor_id, value: u256) -> bool;
91
+ Transfer : (to: actor_id, value: u256) -> bool;
92
+ TransferFrom : (from: actor_id, to: actor_id, value: u256) -> bool;
93
+
94
+ query Allowance : (owner: actor_id, spender: actor_id) -> u256;
95
+ query BalanceOf : (account: actor_id) -> u256;
96
+ query Decimals : () -> u8;
97
+ query Name : () -> str;
98
+ query Symbol : () -> str;
99
+ query TotalSupply : () -> u256;
100
+
101
+ events {
102
+ Approval: struct {
103
+ owner: actor_id,
104
+ spender: actor_id,
105
+ value: u256,
106
+ };
107
+ Transfer: struct {
108
+ from: actor_id,
109
+ to: actor_id,
110
+ value: u256,
111
+ };
112
+ }
113
+ };
114
+ `;
115
+ class SailsCache {
116
+ static instance = null;
117
+ sail = null;
118
+
119
+ // eslint-disable-next-line no-useless-constructor, @typescript-eslint/no-empty-function
120
+ constructor() {}
121
+ static getInstance() {
122
+ if (!SailsCache.instance) {
123
+ SailsCache.instance = new SailsCache();
124
+ }
125
+ return SailsCache.instance;
126
+ }
127
+ async init() {
128
+ if (!this.sail) {
129
+ const parser = await _sailsJsParser.SailsIdlParser.new();
130
+ const sails = new _sailsJs.Sails(parser);
131
+ this.sail = sails.parseIdl(vftIdl);
132
+ }
133
+ }
134
+ get() {
135
+ if (!this.sail) {
136
+ throw new Error('Sails is not init yet');
57
137
  }
58
- return new _sailsJs.TransactionBuilder(this._program.api, this._program.registry, 'send_message', ['Vft', 'TransferFrom', from, to, value], '(String, String, [u8;32], [u8;32], U256)', 'bool', this._program.programId);
59
- }
60
- async allowance(owner, spender, originAddress, value, atBlock) {
61
- const payload = this._program.registry.createType('(String, String, [u8;32], [u8;32])', ['Vft', 'Allowance', owner, spender]).toHex();
62
- const reply = await this._program.api.message.calculateReply({
63
- destination: this._program.programId,
64
- origin: (0, _api.decodeAddress)(originAddress),
65
- payload,
66
- value: value || 0,
67
- gasLimit: this._program.api.blockGasLimit.toBigInt(),
68
- at: atBlock
69
- });
70
- const result = this._program.registry.createType('(String, String, U256)', reply.payload);
71
- return result[2].toBigInt();
72
- }
73
- async balanceOf(account, originAddress, value, atBlock) {
74
- const payload = this._program.registry.createType('(String, String, [u8;32])', ['Vft', 'BalanceOf', account]).toHex();
75
- const reply = await this._program.api.message.calculateReply({
76
- destination: this._program.programId,
77
- origin: (0, _api.decodeAddress)(originAddress),
78
- payload,
79
- value: value || 0,
80
- gasLimit: this._program.api.blockGasLimit.toBigInt(),
81
- at: atBlock
82
- });
83
- const result = this._program.registry.createType('(String, String, U256)', reply.payload);
84
- return result[2].toBigInt();
85
- }
86
- async decimals(originAddress, value, atBlock) {
87
- const payload = this._program.registry.createType('(String, String)', ['Vft', 'Decimals']).toHex();
88
- const reply = await this._program.api.message.calculateReply({
89
- destination: this._program.programId,
90
- origin: (0, _api.decodeAddress)(originAddress),
91
- payload,
92
- value: value || 0,
93
- gasLimit: this._program.api.blockGasLimit.toBigInt(),
94
- at: atBlock
95
- });
96
- const result = this._program.registry.createType('(String, String, u8)', reply.payload);
97
- return result[2].toNumber();
98
- }
99
- async name(originAddress, value, atBlock) {
100
- const payload = this._program.registry.createType('(String, String)', ['Vft', 'Name']).toHex();
101
- const reply = await this._program.api.message.calculateReply({
102
- destination: this._program.programId,
103
- origin: (0, _api.decodeAddress)(originAddress),
104
- payload,
105
- value: value || 0,
106
- gasLimit: this._program.api.blockGasLimit.toBigInt(),
107
- at: atBlock
108
- });
109
- const result = this._program.registry.createType('(String, String, String)', reply.payload);
110
- return result[2].toString();
111
- }
112
- async symbol(originAddress, value, atBlock) {
113
- const payload = this._program.registry.createType('(String, String)', ['Vft', 'Symbol']).toHex();
114
- const reply = await this._program.api.message.calculateReply({
115
- destination: this._program.programId,
116
- origin: (0, _api.decodeAddress)(originAddress),
117
- payload,
118
- value: value || 0,
119
- gasLimit: this._program.api.blockGasLimit.toBigInt(),
120
- at: atBlock
121
- });
122
- const result = this._program.registry.createType('(String, String, String)', reply.payload);
123
- return result[2].toString();
124
- }
125
- async totalSupply(originAddress, value, atBlock) {
126
- const payload = this._program.registry.createType('(String, String)', ['Vft', 'TotalSupply']).toHex();
127
- const reply = await this._program.api.message.calculateReply({
128
- destination: this._program.programId,
129
- origin: (0, _api.decodeAddress)(originAddress),
130
- payload,
131
- value: value || 0,
132
- gasLimit: this._program.api.blockGasLimit.toBigInt(),
133
- at: atBlock
134
- });
135
- const result = this._program.registry.createType('(String, String, U256)', reply.payload);
136
- return result[2].toBigInt();
137
- }
138
- subscribeToApprovalEvent(callback) {
139
- return this._program.api.gearEvents.subscribeToGearEvent('UserMessageSent', _ref => {
140
- let {
141
- data: {
142
- message
143
- }
144
- } = _ref;
145
- if (!message.source.eq(this._program.programId) || !message.destination.eq(_sailsJs.ZERO_ADDRESS)) {
146
- return;
147
- }
148
- const payload = message.payload.toHex();
149
- if ((0, _sailsJs.getServiceNamePrefix)(payload) === 'Vft' && (0, _sailsJs.getFnNamePrefix)(payload) === 'Approval') {
150
- // eslint-disable-next-line node/no-callback-literal,@typescript-eslint/no-floating-promises
151
- callback(this._program.registry.createType('(String, String, {"owner":"[u8;32]","spender":"[u8;32]","value":"U256"})', message.payload)[2].toJSON());
152
- }
153
- });
154
- }
155
- subscribeToTransferEvent(callback) {
156
- return this._program.api.gearEvents.subscribeToGearEvent('UserMessageSent', _ref2 => {
157
- let {
158
- data: {
159
- message
160
- }
161
- } = _ref2;
162
- if (!message.source.eq(this._program.programId) || !message.destination.eq(_sailsJs.ZERO_ADDRESS)) {
163
- return;
164
- }
165
- const payload = message.payload.toHex();
166
- if ((0, _sailsJs.getServiceNamePrefix)(payload) === 'Service' && (0, _sailsJs.getFnNamePrefix)(payload) === 'Transfer') {
167
- // eslint-disable-next-line node/no-callback-literal,@typescript-eslint/no-floating-promises
168
- callback(this._program.registry.createType('(String, String, {"from":"[u8;32]","to":"[u8;32]","value":"U256"})', message.payload)[2].toJSON());
169
- }
170
- });
138
+ return this.sail;
171
139
  }
172
140
  }
173
- exports.VftService = VftService;
141
+ const sailsCache = SailsCache.getInstance();
142
+ exports.sailsCache = sailsCache;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.termAndCondition = exports.staticData = exports.remindNotificationTime = exports.paraSpellChainMap = exports.oldChainPrefix = exports.marketingCampaigns = exports.currencySymbol = exports.crowdloanFunds = exports.buyTokenConfigs = exports.buyServiceInfos = exports.blockedActionsFeatures = exports.blockedActions = exports.StaticKey = void 0;
6
+ exports.termAndCondition = exports.staticData = exports.remindNotificationTime = exports.paraSpellChainMap = exports.oldChainPrefix = exports.marketingCampaigns = exports.currencySymbol = exports.crowdloanFunds = exports.buyTokenConfigs = exports.buyServiceInfos = exports.blockedActionsFeatures = exports.blockedActions = exports.assetHubStakingMap = exports.StaticKey = void 0;
7
7
  var _chainList = require("@subwallet/chain-list");
8
8
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
9
9
  // SPDX-License-Identifier: Apache-2.0
@@ -42,7 +42,10 @@ const oldChainPrefix = require('./oldChainPrefix.json');
42
42
  // eslint-disable-next-line @typescript-eslint/no-var-requires,@typescript-eslint/no-unsafe-assignment
43
43
  exports.oldChainPrefix = oldChainPrefix;
44
44
  const paraSpellChainMap = require('./paraSpellChainMap.json');
45
+ // eslint-disable-next-line @typescript-eslint/no-var-requires,@typescript-eslint/no-unsafe-assignment
45
46
  exports.paraSpellChainMap = paraSpellChainMap;
47
+ const assetHubStakingMap = require('./assetHubStaking.json');
48
+ exports.assetHubStakingMap = assetHubStakingMap;
46
49
  let StaticKey;
47
50
  exports.StaticKey = StaticKey;
48
51
  (function (StaticKey) {
@@ -58,6 +61,7 @@ exports.StaticKey = StaticKey;
58
61
  StaticKey["BLOCKED_ACTIONS"] = "blocked-actions";
59
62
  StaticKey["OLD_CHAIN_PREFIX"] = "old-chain-prefix";
60
63
  StaticKey["PARASPELL_CHAIN_MAP"] = "paraspell-chain-map";
64
+ StaticKey["ASSET_HUB_STAKING_MAP"] = "asset-hub-staking-map";
61
65
  })(StaticKey || (exports.StaticKey = StaticKey = {}));
62
66
  const staticData = {
63
67
  [StaticKey.CHAINS]: Object.values(_chainList.ChainInfoMap),
@@ -71,6 +75,7 @@ const staticData = {
71
75
  [StaticKey.REMIND_NOTIFICATION_TIME]: remindNotificationTime,
72
76
  [StaticKey.BLOCKED_ACTIONS]: blockedActions,
73
77
  [StaticKey.OLD_CHAIN_PREFIX]: oldChainPrefix,
74
- [StaticKey.PARASPELL_CHAIN_MAP]: paraSpellChainMap
78
+ [StaticKey.PARASPELL_CHAIN_MAP]: paraSpellChainMap,
79
+ [StaticKey.ASSET_HUB_STAKING_MAP]: assetHubStakingMap
75
80
  };
76
81
  exports.staticData = staticData;
@@ -7,6 +7,7 @@ import { CardanoProviderError } from '@subwallet/extension-base/background/error
7
7
  import { EvmProviderError } from '@subwallet/extension-base/background/errors/EvmProviderError';
8
8
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
9
9
  import { BitcoinProviderErrorType, CardanoProviderErrorType, EvmProviderErrorType } from '@subwallet/extension-base/background/KoniTypes';
10
+ import { _isSubstrateEvmCompatibleChain } from '@subwallet/extension-base/services/chain-service/utils';
10
11
  import { BasicTxErrorType } from '@subwallet/extension-base/types';
11
12
  import { BN_ZERO, combineEthFee, createPromiseHandler, isSameAddress, reformatAddress, stripUrl, wait } from '@subwallet/extension-base/utils';
12
13
  import { validateAddressNetwork } from '@subwallet/extension-base/utils/cardano';
@@ -247,7 +248,8 @@ export async function validationEvmDataTransactionMiddleware(koni, url, payload)
247
248
  const transactionParams = payload.payloadAfterValidated;
248
249
  const {
249
250
  address: fromAddress,
250
- networkKey
251
+ networkKey,
252
+ pair: pair_
251
253
  } = payload;
252
254
  const evmApi = koni.getEvmApi(networkKey || '');
253
255
  const web3 = evmApi === null || evmApi === void 0 ? void 0 : evmApi.api;
@@ -285,8 +287,25 @@ export async function validationEvmDataTransactionMiddleware(koni, url, payload)
285
287
  if (!fromAddress || !isEthereumAddress(fromAddress)) {
286
288
  handleError('the sender address must be the ethereum address type');
287
289
  }
288
- if (transaction.to && !isEthereumAddress(transaction.to)) {
289
- handleError('invalid recipient address');
290
+ const pair = pair_ || keyring.getPair(fromAddress);
291
+ if (!pair) {
292
+ handleError('Not found address to sign');
293
+ }
294
+ if (pair_ !== null && pair_ !== void 0 && pair_.meta.isSubstrateECDSA) {
295
+ handleError('Substrate account can not send this transaction');
296
+ }
297
+ const evmNetwork = koni.getChainInfo(networkKey || '');
298
+ if (transaction.to) {
299
+ if (!isEthereumAddress(transaction.to)) {
300
+ handleError('invalid recipient address');
301
+ } else {
302
+ try {
303
+ const pairTo = keyring.getPair(transaction.to);
304
+ if (pairTo && pairTo.meta.isSubstrateECDSA && !_isSubstrateEvmCompatibleChain(evmNetwork)) {
305
+ handleError('substrate account cannot receive this token');
306
+ }
307
+ } catch (e) {}
308
+ }
290
309
  }
291
310
  if (fromAddress === transaction.to) {
292
311
  handleError('receiving address must be different from sending address');
@@ -382,7 +401,6 @@ export async function validationEvmDataTransactionMiddleware(koni, url, payload)
382
401
  handleError(e.message);
383
402
  }
384
403
  const hasError = errors && errors.length > 0 || !networkKey;
385
- const evmNetwork = koni.getChainInfo(networkKey || '');
386
404
  let isToContract = false;
387
405
  let hashPayload = '';
388
406
  let parseData = '';
@@ -433,6 +451,12 @@ export async function validationEvmSignMessageMiddleware(koni, url, payload_) {
433
451
  handleError('Not found address or payload to sign');
434
452
  }
435
453
  const pair = pair_ || keyring.getPair(address);
454
+ if (!pair) {
455
+ handleError('Not found address to sign');
456
+ }
457
+ if (pair_ !== null && pair_ !== void 0 && pair_.meta.isSubstrateECDSA) {
458
+ handleError('Substrate account can not sign this message');
459
+ }
436
460
  if (method) {
437
461
  if (['eth_sign', 'personal_sign', 'eth_signTypedData', 'eth_signTypedData_v1', 'eth_signTypedData_v3', 'eth_signTypedData_v4'].indexOf(method) < 0) {
438
462
  handleError('Unsupported action');
@@ -984,6 +1008,9 @@ export function convertErrorMessage(message_, name) {
984
1008
  if (message.includes('insufficient balance') || message.includes('insufficient funds')) {
985
1009
  return [t('Insufficient balance on the sender address. Top up your balance and try again'), t('Unable to sign transaction')];
986
1010
  }
1011
+ if (message.includes('substrate') && message.includes('receive this token')) {
1012
+ return [t('The recipient account is a Ledger Polkadot (EVM) account, which is not supported for this transaction. Change recipient account and try again'), t('Invalid account type')];
1013
+ }
987
1014
 
988
1015
  // Sign Message
989
1016
  if (message.includes('not found address or payload to sign')) {
package/core/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { _ChainInfo } from '@subwallet/chain-list/types';
1
+ import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { AccountJson } from '@subwallet/extension-base/types';
3
- export declare type LedgerMustCheckType = 'polkadot' | 'migration' | 'unnecessary';
3
+ export declare type LedgerMustCheckType = 'polkadot' | 'migration' | 'polkadot_ecdsa' | 'unnecessary';
4
4
  export declare enum ValidationCondition {
5
5
  IS_NOT_NULL = "IS_NOT_NULL",
6
6
  IS_ADDRESS = "IS_ADDRESS",
@@ -20,6 +20,7 @@ export declare enum ActionType {
20
20
  export interface ValidateRecipientParams {
21
21
  srcChain: string;
22
22
  destChainInfo: _ChainInfo;
23
+ assetInfo?: _ChainAsset;
23
24
  fromAddress: string;
24
25
  toAddress: string;
25
26
  account: AccountJson | null;
package/core/utils.js CHANGED
@@ -4,9 +4,11 @@
4
4
  import { _AssetType } from '@subwallet/chain-list/types';
5
5
  import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
6
6
  import { BalanceAccountType } from '@subwallet/extension-base/core/substrate/types';
7
+ import { ActionType } from '@subwallet/extension-base/core/types';
7
8
  import { tonAddressInfo } from '@subwallet/extension-base/services/balance-service/helpers/subscribe/ton/utils';
8
- import { _getTokenOnChainAssetId, _getXcmAssetMultilocation, _isBridgedToken, _isChainBitcoinCompatible, _isChainCardanoCompatible, _isChainEvmCompatible, _isChainSubstrateCompatible, _isChainTonCompatible } from '@subwallet/extension-base/services/chain-service/utils';
9
- import { isAddressAndChainCompatible, isSameAddress, reformatAddress } from '@subwallet/extension-base/utils';
9
+ import { _getTokenOnChainAssetId, _getXcmAssetMultilocation, _isBridgedToken, _isChainBitcoinCompatible, _isChainCardanoCompatible, _isChainCompatibleLedgerEvm, _isChainEvmCompatible, _isChainSubstrateCompatible, _isChainTonCompatible, _isSubstrateEvmCompatibleChain } from '@subwallet/extension-base/services/chain-service/utils';
10
+ import { AccountChainType, AccountSignMode } from '@subwallet/extension-base/types';
11
+ import { isAddressAndChainCompatible, isSameAddress, isSubstrateEcdsaLedgerAssetSupported, reformatAddress } from '@subwallet/extension-base/utils';
10
12
  import { isAddress, isCardanoTestnetAddress, isTonAddress } from '@subwallet/keyring';
11
13
  import { getBitcoinAddressInfo, validateBitcoinAddress } from '@subwallet/keyring/utils';
12
14
  import { isEthereumAddress } from '@polkadot/util-crypto';
@@ -122,7 +124,9 @@ export function _isNotDuplicateAddress(validateRecipientParams) {
122
124
  export function _isSupportLedgerAccount(validateRecipientParams) {
123
125
  const {
124
126
  account,
127
+ actionType,
125
128
  allowLedgerGenerics,
129
+ assetInfo,
126
130
  destChainInfo
127
131
  } = validateRecipientParams;
128
132
  if (account !== null && account !== void 0 && account.isHardware) {
@@ -135,6 +139,24 @@ export function _isSupportLedgerAccount(validateRecipientParams) {
135
139
  return 'Your Ledger account is not supported by {{network}} network.'.replace('{{network}}', destChainName);
136
140
  }
137
141
  } else {
142
+ if (account.chainType === AccountChainType.ETHEREUM) {
143
+ // For ecdsa substrate account in polkadot ledger app
144
+ if (account.signMode === AccountSignMode.ECDSA_SUBSTRATE_LEDGER) {
145
+ if (actionType === ActionType.SEND_NFT) {
146
+ return 'Ledger Polkadot (EVM) address is not supported for NFT transfer';
147
+ }
148
+ if (!_isSubstrateEvmCompatibleChain(destChainInfo)) {
149
+ return 'Ledger Polkadot (EVM) address is not supported for this transfer';
150
+ } else if (assetInfo && !isSubstrateEcdsaLedgerAssetSupported(assetInfo, destChainInfo)) {
151
+ return 'Ledger Polkadot (EVM) address is not supported for this transfer';
152
+ }
153
+ } else {
154
+ if (!_isChainCompatibleLedgerEvm(destChainInfo)) {
155
+ return 'Ledger EVM address is not supported for this transfer';
156
+ }
157
+ }
158
+ }
159
+
138
160
  // For ledger generic
139
161
  const ledgerCheck = ledgerMustCheckNetwork(account);
140
162
  if (ledgerCheck !== 'unnecessary' && !allowLedgerGenerics.includes(destChainInfo.slug)) {
@@ -46,10 +46,11 @@ export default class OrdinalNftApi extends BaseNftApi {
46
46
  this.subscanService = SubscanService.getInstance();
47
47
  }
48
48
  async handleNft(address, handleNftParams) {
49
- const events = await this.subscanService.getAccountRemarkEvents(this.subscanChain, address);
49
+ const groupId = this.subscanService.getGroupId();
50
+ const events = await this.subscanService.getAccountRemarkEvents(groupId, this.subscanChain, address);
50
51
  if (events && events.length) {
51
52
  const extrinsicIds = events.map(data => data.extrinsic_index);
52
- const extrinsicParams = await this.subscanService.getExtrinsicParams(this.subscanChain, extrinsicIds);
53
+ const extrinsicParams = await this.subscanService.getExtrinsicParams(groupId, this.subscanChain, extrinsicIds);
53
54
  const items = [];
54
55
  for (const data of extrinsicParams) {
55
56
  const {
@@ -11,6 +11,7 @@ import { CampaignDataType, ChainType, ExternalRequestPromiseStatus, ExtrinsicTyp
11
11
  import { _SUPPORT_TOKEN_PAY_FEE_GROUP, ALL_ACCOUNT_KEY, BTC_DUST_AMOUNT, LATEST_SESSION } from '@subwallet/extension-base/constants';
12
12
  import { additionalValidateTransferForRecipient, validateTransferRequest, validateXcmMinAmountToMythos, validateXcmTransferRequest } from '@subwallet/extension-base/core/logic-validation/transfer';
13
13
  import { _isSnowBridgeXcm } from '@subwallet/extension-base/core/substrate/xcm-parser';
14
+ import { ActionType } from '@subwallet/extension-base/core/types';
14
15
  import { _isSufficientToken } from '@subwallet/extension-base/core/utils';
15
16
  import { ALLOWED_PATH } from '@subwallet/extension-base/defaults';
16
17
  import { getERC20SpendingApprovalTx } from '@subwallet/extension-base/koni/api/contract-handler/evm/web3';
@@ -47,7 +48,7 @@ import { isProposalExpired, isSupportWalletConnectChain, isSupportWalletConnectN
47
48
  import { SWStorage } from '@subwallet/extension-base/storage';
48
49
  import { AccountsStore } from '@subwallet/extension-base/stores';
49
50
  import { AccountSignMode, BasicTxErrorType, BasicTxWarningCode, CommonStepType, EarningProcessType, ProcessType, StakingTxErrorType, StepStatus, SwapFeeType, YieldPoolType, YieldStepType } from '@subwallet/extension-base/types';
50
- import { _analyzeAddress, calculateMaxTransferable, combineAllAccountProxy, combineBitcoinFee, createPromiseHandler, createTransactionFromRLP, detectTransferTxType, filterUneconomicalUtxos, getAccountSignMode, getSizeInfo, getTransferableBitcoinUtxos, isSameAddress, MODULE_SUPPORT, reformatAddress, signatureToHex, transformAccounts, transformAddresses, uniqueStringArray } from '@subwallet/extension-base/utils';
51
+ import { _analyzeAddress, calculateMaxTransferable, combineAllAccountProxy, combineBitcoinFee, createPromiseHandler, createTransactionFromRLP, detectTransferTxType, filterUneconomicalUtxos, getAccountSignMode, getSizeInfo, getTransferableBitcoinUtxos, isSameAddress, isSubstrateEcdsaLedgerAssetSupported, MODULE_SUPPORT, reformatAddress, signatureToHex, transformAccounts, transformAddresses, uniqueStringArray } from '@subwallet/extension-base/utils';
51
52
  import { parseContractInput, parseEvmRlp } from '@subwallet/extension-base/utils/eth/parseTransaction';
52
53
  import { getId } from '@subwallet/extension-base/utils/getId';
53
54
  import { getKeypairTypeByAddress, isAddress, isCardanoAddress, isSubstrateAddress, isTonAddress } from '@subwallet/keyring';
@@ -296,16 +297,32 @@ export default class KoniExtension {
296
297
  }
297
298
  async subscribeInputAddressData(request, id, port) {
298
299
  const {
300
+ actionType,
299
301
  chain,
300
- data
302
+ data,
303
+ token
301
304
  } = request;
302
305
  const cb = createSubscription(id, port);
303
- const combineFunction = async (chainInfoMap, accountProxyMap, _contacts) => {
306
+ const combineFunction = async (chainInfoMap, tokenInfoMap, accountProxyMap, _contacts) => {
304
307
  const accountProxies = Object.values(accountProxyMap);
305
308
  const contacts = transformAddresses(_contacts);
306
309
  const chainInfo = chainInfoMap[chain];
310
+ const tokenInfo = tokenInfoMap[token || ''];
307
311
  const substrateApi = this.#koniState.chainService.getSubstrateApi(chain);
308
- const rs = await _analyzeAddress(data, accountProxies, contacts, chainInfo, substrateApi);
312
+ const accountProxiesFiltered = accountProxies.filter(accountProxy => {
313
+ var _accountProxy$account;
314
+ const signMode = (_accountProxy$account = accountProxy.accounts[0]) === null || _accountProxy$account === void 0 ? void 0 : _accountProxy$account.signMode;
315
+ if (signMode === AccountSignMode.ECDSA_SUBSTRATE_LEDGER) {
316
+ if (actionType === ActionType.SEND_NFT) {
317
+ return false;
318
+ }
319
+ if (tokenInfo) {
320
+ return isSubstrateEcdsaLedgerAssetSupported(tokenInfo, chainInfo);
321
+ }
322
+ }
323
+ return true;
324
+ });
325
+ const rs = await _analyzeAddress(data, accountProxiesFiltered, contacts, chainInfo, substrateApi);
309
326
  return {
310
327
  id,
311
328
  ...rs
@@ -314,16 +331,19 @@ export default class KoniExtension {
314
331
  const accountObservable = this.#koniState.keyringService.context.observable.accounts;
315
332
  const contactObservable = this.#koniState.keyringService.context.observable.contacts;
316
333
  const chainInfoMapObservable = this.#koniState.chainService.subscribeChainInfoMap().asObservable();
334
+ const tokenInfoMapObservable = this.#koniState.chainService.subscribeAssetRegistry().asObservable();
317
335
  const subscription = combineLatest({
318
336
  chainInfoMap: chainInfoMapObservable,
337
+ tokenInfoMap: tokenInfoMapObservable,
319
338
  accountProxies: accountObservable,
320
339
  contacts: contactObservable
321
340
  }).subscribe(({
322
341
  accountProxies,
323
342
  chainInfoMap,
324
- contacts
343
+ contacts,
344
+ tokenInfoMap
325
345
  }) => {
326
- combineFunction(chainInfoMap, accountProxies, contacts).then(rs => cb(rs)).catch(console.error);
346
+ combineFunction(chainInfoMap, tokenInfoMap, accountProxies, contacts).then(rs => cb(rs)).catch(console.error);
327
347
  });
328
348
  this.createUnsubscriptionHandle(id, () => {
329
349
  subscription.unsubscribe();
@@ -334,7 +354,8 @@ export default class KoniExtension {
334
354
  const accountProxyMap = this.#koniState.keyringService.context.value.accounts;
335
355
  const contacts = this.#koniState.keyringService.context.value.contacts;
336
356
  const chainInfoMap = this.#koniState.chainService.getChainInfoMap();
337
- return combineFunction(chainInfoMap, accountProxyMap, contacts);
357
+ const tokenInfoMap = this.#koniState.chainService.getAssetRegistry();
358
+ return combineFunction(chainInfoMap, tokenInfoMap, accountProxyMap, contacts);
338
359
  }
339
360
 
340
361
  /**
@@ -1242,6 +1263,8 @@ export default class KoniExtension {
1242
1263
  const isTransferLocalTokenAndPayThatTokenAsFee = !isTransferNativeToken && tokenPayFeeSlug === tokenSlug;
1243
1264
  const isCustomTokenPayFeeAssetHub = tokenPayFeeSlug && !_isNativeTokenBySlug(tokenPayFeeSlug) && _SUPPORT_TOKEN_PAY_FEE_GROUP.assetHub.includes(chain);
1244
1265
  const isCustomTokenPayFeeHydration = tokenPayFeeSlug && !_isNativeTokenBySlug(tokenPayFeeSlug) && _SUPPORT_TOKEN_PAY_FEE_GROUP.hydration.includes(chain);
1266
+ const pairFrom = keyring.getPair(from);
1267
+ const isSubstrateECDSATransaction = pairFrom.meta.isSubstrateECDSA;
1245
1268
  const extrinsicType = isTransferNativeToken ? ExtrinsicType.TRANSFER_BALANCE : ExtrinsicType.TRANSFER_TOKEN;
1246
1269
  let chainType = ChainType.SUBSTRATE;
1247
1270
  const transferAmount = {
@@ -1258,7 +1281,7 @@ export default class KoniExtension {
1258
1281
  extrinsicType
1259
1282
  });
1260
1283
  try {
1261
- if (isEthereumAddress(from) && isEthereumAddress(to) && _isTokenTransferredByEvm(transferTokenInfo)) {
1284
+ if (isEthereumAddress(from) && isEthereumAddress(to) && _isTokenTransferredByEvm(transferTokenInfo) && !isSubstrateECDSATransaction) {
1262
1285
  chainType = ChainType.EVM;
1263
1286
  const txVal = transferAll ? transferTokenAvailable.value : value || '0';
1264
1287
  const evmApi = this.#koniState.getEvmApi(chain);
@@ -41,7 +41,7 @@ import TransactionService from '@subwallet/extension-base/services/transaction-s
41
41
  import WalletConnectService from '@subwallet/extension-base/services/wallet-connect-service';
42
42
  import { SWStorage } from '@subwallet/extension-base/storage';
43
43
  import { BasicTxErrorType } from '@subwallet/extension-base/types';
44
- import { addLazy, isManifestV3, isSameAddress, reformatAddress, stripUrl, targetIsWeb } from '@subwallet/extension-base/utils';
44
+ import { addLazy, isManifestV3, isSameAddress, reformatAddress, sailsCache, stripUrl, targetIsWeb } from '@subwallet/extension-base/utils';
45
45
  import { convertCardanoHexToBech32, validateAddressNetwork } from '@subwallet/extension-base/utils/cardano';
46
46
  import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
47
47
  import subwalletApiSdk from '@subwallet/subwallet-api-sdk';
@@ -238,6 +238,9 @@ export default class KoniState {
238
238
  this.afterChainServiceInit();
239
239
  });
240
240
 
241
+ // init sails
242
+ await sailsCache.init();
243
+
241
244
  // Mark app is ready
242
245
  this.eventService.emit('general.init', true);
243
246
  }
@@ -26,7 +26,7 @@ import Web3 from 'web3';
26
26
  import { checkIfDenied } from '@polkadot/phishing';
27
27
  import { hexStripPrefix, isArray, isNumber, u8aToHex } from '@polkadot/util';
28
28
  import { isEthereumAddress } from '@polkadot/util-crypto';
29
- function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthTypes) {
29
+ function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthTypes, isSubstrateConnector) {
30
30
  const accountSelected = authInfo ? authInfo.isAllowed ? Object.keys(authInfo.isAllowedMap).filter(address => authInfo.isAllowedMap[address]) : [] : [];
31
31
  const authTypeFilter = ({
32
32
  json,
@@ -55,6 +55,12 @@ function transformAccountsV2(accounts, anyType = false, authInfo, accountAuthTyp
55
55
  if (type === 'cardano' && json.meta.isReadOnly) {
56
56
  return false;
57
57
  }
58
+ const canConnectSubstrateEcdsa = (authInfo === null || authInfo === void 0 ? void 0 : authInfo.canConnectSubstrateEcdsa) && isSubstrateConnector;
59
+
60
+ // If the dApp has not connected to the Substrate type yet, we do not return Substrate ECDSA accounts.
61
+ if (type === 'ethereum' && json.meta.isSubstrateECDSA && !canConnectSubstrateEcdsa) {
62
+ return false;
63
+ }
58
64
  return true;
59
65
  } else {
60
66
  return true;
@@ -267,7 +273,8 @@ export default class KoniTabs {
267
273
  }
268
274
  async accountsListV2(url, {
269
275
  accountAuthType,
270
- anyType
276
+ anyType,
277
+ isSubstrateConnector
271
278
  }) {
272
279
  const authInfo = await this.getAuthInfo(url);
273
280
  const accountAuthTypes = [];
@@ -287,7 +294,7 @@ export default class KoniTabs {
287
294
  accountAuthTypes.push('cardano');
288
295
  }
289
296
  }
290
- return transformAccountsV2(this.#koniState.keyringService.context.pairs, anyType, authInfo, accountAuthTypes);
297
+ return transformAccountsV2(this.#koniState.keyringService.context.pairs, anyType, authInfo, accountAuthTypes, isSubstrateConnector);
291
298
  }
292
299
 
293
300
  // TODO: Update logic
@@ -311,7 +318,7 @@ export default class KoniTabs {
311
318
  }
312
319
  }
313
320
  const accounts = this.#koniState.keyringService.context.pairs;
314
- return cb(transformAccountsV2(accounts, false, authInfo, accountAuthTypes));
321
+ return cb(transformAccountsV2(accounts, false, authInfo, accountAuthTypes, true));
315
322
  }).catch(console.error);
316
323
  }),
317
324
  url