@subwallet/extension-base 1.2.14-0 → 1.2.16-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/background/KoniTypes.d.ts +6 -1
- package/cjs/core/substrate/nominationpools-pallet.js +2 -1
- package/cjs/koni/api/nft/config.js +9 -5
- package/cjs/koni/api/nft/index.js +9 -1
- package/cjs/koni/api/nft/unique_network_nft/index.js +12 -20
- package/cjs/koni/background/handlers/Extension.js +45 -7
- package/cjs/koni/background/handlers/State.js +11 -1
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/subscribe/index.js +1 -1
- package/cjs/services/balance-service/helpers/subscribe/substrate/gear.js +135 -0
- package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +9 -62
- package/cjs/services/balance-service/transfer/token.js +4 -3
- package/cjs/services/chain-service/constants.js +1 -0
- package/cjs/services/chain-service/handler/SubstrateApi.js +3 -1
- package/cjs/services/chain-service/handler/SubstrateChainHandler.js +21 -26
- package/cjs/services/chain-service/health-check/constants/index.js +4 -4
- package/cjs/services/chain-service/health-check/utils/asset-info.js +23 -6
- package/cjs/services/chain-service/health-check/utils/chain-info.js +25 -2
- package/cjs/services/chain-service/health-check/utils/new-utils/asset-asset-validate.js +160 -0
- package/cjs/services/chain-service/health-check/utils/new-utils/asset-validate.js +45 -0
- package/cjs/services/chain-service/health-check/utils/new-utils/chain-asset-validate.js +73 -0
- package/cjs/services/chain-service/health-check/utils/new-utils/chain-validate.js +34 -0
- package/cjs/services/chain-service/index.js +77 -3
- package/cjs/services/chain-service/types.js +1 -1
- package/cjs/services/chain-service/utils/index.js +18 -12
- package/cjs/services/earning-service/handlers/liquid-staking/acala.js +49 -19
- package/cjs/services/earning-service/service.js +3 -0
- package/cjs/services/migration-service/scripts/databases/ClearMetadataDatabase.js +16 -0
- package/cjs/services/migration-service/scripts/index.js +7 -7
- package/cjs/services/price-service/coingecko.js +57 -32
- package/cjs/services/price-service/index.js +30 -11
- package/cjs/services/transaction-service/index.js +12 -7
- package/cjs/utils/gear/combine.js +28 -0
- package/cjs/utils/gear/grc20.js +56 -49
- package/cjs/utils/gear/index.js +22 -0
- package/cjs/utils/gear/vft.js +173 -0
- package/cjs/utils/metadata.js +45 -34
- package/core/substrate/nominationpools-pallet.js +2 -1
- package/koni/api/nft/config.d.ts +1 -0
- package/koni/api/nft/config.js +3 -1
- package/koni/api/nft/index.js +9 -1
- package/koni/api/nft/unique_network_nft/index.js +12 -20
- package/koni/background/handlers/Extension.d.ts +2 -0
- package/koni/background/handlers/Extension.js +37 -1
- package/koni/background/handlers/State.d.ts +2 -0
- package/koni/background/handlers/State.js +11 -1
- package/package.json +44 -8
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/subscribe/index.js +1 -1
- package/services/balance-service/helpers/subscribe/substrate/gear.d.ts +4 -0
- package/services/balance-service/helpers/subscribe/substrate/gear.js +123 -0
- package/services/balance-service/helpers/subscribe/substrate/index.js +10 -61
- package/services/balance-service/transfer/token.js +5 -4
- package/services/chain-service/constants.d.ts +1 -0
- package/services/chain-service/constants.js +1 -0
- package/services/chain-service/handler/SubstrateApi.d.ts +1 -1
- package/services/chain-service/handler/SubstrateApi.js +3 -1
- package/services/chain-service/handler/SubstrateChainHandler.d.ts +1 -0
- package/services/chain-service/handler/SubstrateChainHandler.js +22 -27
- package/services/chain-service/health-check/constants/index.js +4 -4
- package/services/chain-service/health-check/utils/asset-info.d.ts +1 -0
- package/services/chain-service/health-check/utils/asset-info.js +20 -4
- package/services/chain-service/health-check/utils/chain-info.d.ts +4 -2
- package/services/chain-service/health-check/utils/chain-info.js +20 -0
- package/services/chain-service/health-check/utils/new-utils/asset-asset-validate.d.ts +10 -0
- package/services/chain-service/health-check/utils/new-utils/asset-asset-validate.js +146 -0
- package/services/chain-service/health-check/utils/new-utils/asset-validate.d.ts +3 -0
- package/services/chain-service/health-check/utils/new-utils/asset-validate.js +38 -0
- package/services/chain-service/health-check/utils/new-utils/chain-asset-validate.d.ts +5 -0
- package/services/chain-service/health-check/utils/new-utils/chain-asset-validate.js +64 -0
- package/services/chain-service/health-check/utils/new-utils/chain-validate.d.ts +4 -0
- package/services/chain-service/health-check/utils/new-utils/chain-validate.js +26 -0
- package/services/chain-service/index.d.ts +4 -0
- package/services/chain-service/index.js +78 -4
- package/services/chain-service/types.d.ts +6 -0
- package/services/chain-service/types.js +1 -1
- package/services/chain-service/utils/index.d.ts +1 -0
- package/services/chain-service/utils/index.js +16 -12
- package/services/earning-service/handlers/liquid-staking/acala.js +46 -17
- package/services/earning-service/service.js +3 -0
- package/services/migration-service/scripts/databases/ClearMetadataDatabase.js +16 -0
- package/services/migration-service/scripts/index.js +7 -7
- package/services/price-service/coingecko.js +54 -32
- package/services/price-service/index.js +29 -11
- package/services/transaction-service/index.js +13 -8
- package/types/metadata.d.ts +9 -2
- package/utils/gear/combine.d.ts +10 -0
- package/utils/gear/combine.js +18 -0
- package/utils/gear/grc20.d.ts +18 -20
- package/utils/gear/grc20.js +53 -45
- package/utils/gear/index.d.ts +2 -0
- package/utils/gear/index.js +3 -1
- package/utils/gear/vft.d.ts +36 -0
- package/utils/gear/vft.js +162 -0
- package/utils/metadata.d.ts +7 -2
- package/utils/metadata.js +41 -31
|
@@ -14,7 +14,7 @@ import { getBaseTransactionInfo, getTransactionId, isSubstrateTransaction } from
|
|
|
14
14
|
import { getExplorerLink, parseTransactionData } from '@subwallet/extension-base/services/transaction-service/utils';
|
|
15
15
|
import { isWalletConnectRequest } from '@subwallet/extension-base/services/wallet-connect-service/helpers';
|
|
16
16
|
import { YieldPoolType } from '@subwallet/extension-base/types';
|
|
17
|
-
import { _isRuntimeUpdated, anyNumberToBN,
|
|
17
|
+
import { _isRuntimeUpdated, anyNumberToBN, reformatAddress } from '@subwallet/extension-base/utils';
|
|
18
18
|
import { mergeTransactionAndSignature } from '@subwallet/extension-base/utils/eth/mergeTransactionAndSignature';
|
|
19
19
|
import { isContractAddress, parseContractInput } from '@subwallet/extension-base/utils/eth/parseTransaction';
|
|
20
20
|
import { BN_ZERO } from '@subwallet/extension-base/utils/number';
|
|
@@ -1030,20 +1030,25 @@ export default class TransactionService {
|
|
|
1030
1030
|
const signerOption = {
|
|
1031
1031
|
signer: {
|
|
1032
1032
|
signPayload: async payload => {
|
|
1033
|
-
const
|
|
1033
|
+
const {
|
|
1034
|
+
signature,
|
|
1035
|
+
signedTransaction
|
|
1036
|
+
} = await this.state.requestService.signInternalTransaction(id, address, url || EXTENSION_REQUEST_URL, payload);
|
|
1034
1037
|
return {
|
|
1035
1038
|
id: new Date().getTime(),
|
|
1036
|
-
signature
|
|
1039
|
+
signature,
|
|
1040
|
+
signedTransaction
|
|
1037
1041
|
};
|
|
1038
1042
|
}
|
|
1039
|
-
}
|
|
1043
|
+
},
|
|
1044
|
+
withSignedTransaction: true
|
|
1040
1045
|
};
|
|
1041
1046
|
if (_isRuntimeUpdated(signedExtensions)) {
|
|
1042
|
-
|
|
1043
|
-
|
|
1047
|
+
const metadataHash = await this.state.chainService.calculateMetadataHash(chain);
|
|
1048
|
+
if (metadataHash) {
|
|
1044
1049
|
signerOption.mode = 1;
|
|
1045
|
-
signerOption.metadataHash =
|
|
1046
|
-
}
|
|
1050
|
+
signerOption.metadataHash = metadataHash;
|
|
1051
|
+
}
|
|
1047
1052
|
}
|
|
1048
1053
|
extrinsic.signAsync(address, signerOption).then(async rs => {
|
|
1049
1054
|
// Emit signed event
|
package/types/metadata.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
export interface
|
|
2
|
-
|
|
1
|
+
export interface RequestMetadataHash {
|
|
2
|
+
chain: string;
|
|
3
3
|
}
|
|
4
4
|
export interface ResponseMetadataHash {
|
|
5
5
|
metadataHash: string;
|
|
6
6
|
}
|
|
7
|
+
export interface RequestShortenMetadata {
|
|
8
|
+
chain: string;
|
|
9
|
+
txBlob: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ResponseShortenMetadata {
|
|
12
|
+
txMetadata: string;
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ApiPromise } from '@polkadot/api';
|
|
2
|
+
import { GRC20 } from './grc20';
|
|
3
|
+
import { VFT } from './vft';
|
|
4
|
+
export declare const DEFAULT_GEAR_ADDRESS: {
|
|
5
|
+
ALICE: string;
|
|
6
|
+
BOB: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const GEAR_DEFAULT_ADDRESS = "5EYCAe5ijiYfAXEth5DGRKiKuVjTXQKr877tUPz6eLz2t9aG";
|
|
9
|
+
export declare function getGRC20ContractPromise(apiPromise: ApiPromise, contractAddress: string): GRC20;
|
|
10
|
+
export declare function getVFTContractPromise(apiPromise: ApiPromise, contractAddress: string): VFT;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { GRC20 } from "./grc20.js";
|
|
5
|
+
import { VFT } from "./vft.js";
|
|
6
|
+
export const DEFAULT_GEAR_ADDRESS = {
|
|
7
|
+
ALICE: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
|
|
8
|
+
BOB: '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'
|
|
9
|
+
};
|
|
10
|
+
export const GEAR_DEFAULT_ADDRESS = '5EYCAe5ijiYfAXEth5DGRKiKuVjTXQKr877tUPz6eLz2t9aG';
|
|
11
|
+
export function getGRC20ContractPromise(apiPromise, contractAddress) {
|
|
12
|
+
const gearApi = apiPromise;
|
|
13
|
+
return new GRC20(gearApi, contractAddress);
|
|
14
|
+
}
|
|
15
|
+
export function getVFTContractPromise(apiPromise, contractAddress) {
|
|
16
|
+
const gearApi = apiPromise;
|
|
17
|
+
return new VFT(gearApi, contractAddress);
|
|
18
|
+
}
|
package/utils/gear/grc20.d.ts
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { GearApi } from '@gear-js/api';
|
|
3
|
-
import { TransactionBuilder } from 'sails-js';
|
|
4
|
-
import {
|
|
5
|
-
export declare type ActorId = `0x${string}`;
|
|
6
|
-
export declare type U256 = bigint;
|
|
7
|
-
export declare const DEFAULT_GEAR_ADDRESS: {
|
|
8
|
-
ALICE: string;
|
|
9
|
-
BOB: string;
|
|
10
|
-
};
|
|
3
|
+
import { ActorId, TransactionBuilder } from 'sails-js';
|
|
4
|
+
import { TypeRegistry } from '@polkadot/types';
|
|
11
5
|
export declare class GRC20 {
|
|
12
6
|
api: GearApi;
|
|
13
7
|
programId: `0x${string}`;
|
|
14
|
-
|
|
8
|
+
readonly registry: TypeRegistry;
|
|
9
|
+
readonly service: Grc20Service;
|
|
15
10
|
constructor(api: GearApi, programId?: `0x${string}`);
|
|
16
|
-
newCtorFromCode(code: Uint8Array | Buffer, name: string, symbol: string, decimals: number
|
|
17
|
-
newCtorFromCodeId(codeId: `0x${string}`, name: string, symbol: string, decimals: number
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
newCtorFromCode(code: Uint8Array | Buffer, name: string, symbol: string, decimals: number): TransactionBuilder<null>;
|
|
12
|
+
newCtorFromCodeId(codeId: `0x${string}`, name: string, symbol: string, decimals: number): TransactionBuilder<null>;
|
|
13
|
+
}
|
|
14
|
+
export declare class Grc20Service {
|
|
15
|
+
private _program;
|
|
16
|
+
constructor(_program: GRC20);
|
|
17
|
+
approve(spender: ActorId, value: number | string | bigint): TransactionBuilder<boolean>;
|
|
18
|
+
fromTransfer(from: ActorId, to: ActorId, value: number | string | bigint): TransactionBuilder<boolean>;
|
|
19
|
+
setBalance(newBalance: number | string | bigint): TransactionBuilder<boolean>;
|
|
20
|
+
transfer(to: ActorId, value: number | string | bigint): TransactionBuilder<boolean>;
|
|
21
|
+
allowance(owner: ActorId, spender: ActorId, originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<bigint>;
|
|
22
|
+
balanceOf(owner: ActorId, originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<bigint>;
|
|
23
|
+
decimals(originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<number>;
|
|
25
24
|
name(originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<string>;
|
|
26
25
|
symbol(originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<string>;
|
|
27
|
-
totalSupply(originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<
|
|
26
|
+
totalSupply(originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<bigint>;
|
|
28
27
|
}
|
|
29
|
-
export declare function getGRC20ContractPromise(apiPromise: ApiPromise, contractAddress: string): GRC20;
|
package/utils/gear/grc20.js
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
// Copyright 2019-2022 @subwallet/extension-base
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
// https://github.com/breathx/gear-erc20/blob/master/js/src/lib.ts
|
|
5
|
-
|
|
6
4
|
import { decodeAddress } from '@gear-js/api';
|
|
7
5
|
import { TransactionBuilder } from 'sails-js';
|
|
8
6
|
import { TypeRegistry } from '@polkadot/types';
|
|
9
|
-
export const DEFAULT_GEAR_ADDRESS = {
|
|
10
|
-
ALICE: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
|
|
11
|
-
BOB: '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'
|
|
12
|
-
};
|
|
13
7
|
export class GRC20 {
|
|
14
8
|
constructor(api, programId = '0x') {
|
|
15
9
|
this.api = api;
|
|
@@ -23,6 +17,7 @@ export class GRC20 {
|
|
|
23
17
|
types
|
|
24
18
|
});
|
|
25
19
|
this.registry.register(types);
|
|
20
|
+
this.service = new Grc20Service(this);
|
|
26
21
|
}
|
|
27
22
|
newCtorFromCode(code, name, symbol, decimals) {
|
|
28
23
|
const builder = new TransactionBuilder(this.api, this.registry, 'upload_program', ['New', name, symbol, decimals], '(String, String, String, u8)', 'String', code);
|
|
@@ -34,98 +29,111 @@ export class GRC20 {
|
|
|
34
29
|
this.programId = builder.programId;
|
|
35
30
|
return builder;
|
|
36
31
|
}
|
|
32
|
+
}
|
|
33
|
+
export class Grc20Service {
|
|
34
|
+
constructor(_program) {
|
|
35
|
+
this._program = _program;
|
|
36
|
+
}
|
|
37
37
|
approve(spender, value) {
|
|
38
|
-
|
|
38
|
+
if (!this._program.programId) {
|
|
39
|
+
throw new Error('Program ID is not set');
|
|
40
|
+
}
|
|
41
|
+
return new TransactionBuilder(this._program.api, this._program.registry, 'send_message', ['Approve', spender, value], '(String, ActorId, U256)', 'bool', this._program.programId);
|
|
39
42
|
}
|
|
40
43
|
fromTransfer(from, to, value) {
|
|
41
|
-
|
|
44
|
+
if (!this._program.programId) {
|
|
45
|
+
throw new Error('Program ID is not set');
|
|
46
|
+
}
|
|
47
|
+
return new TransactionBuilder(this._program.api, this._program.registry, 'send_message', ['FromTransfer', from, to, value], '(String, ActorId, ActorId, U256)', 'bool', this._program.programId);
|
|
42
48
|
}
|
|
43
49
|
setBalance(newBalance) {
|
|
44
|
-
|
|
50
|
+
if (!this._program.programId) {
|
|
51
|
+
throw new Error('Program ID is not set');
|
|
52
|
+
}
|
|
53
|
+
return new TransactionBuilder(this._program.api, this._program.registry, 'send_message', ['SetBalance', newBalance], '(String, U256)', 'bool', this._program.programId);
|
|
45
54
|
}
|
|
46
55
|
transfer(to, value) {
|
|
47
|
-
|
|
56
|
+
if (!this._program.programId) {
|
|
57
|
+
throw new Error('Program ID is not set');
|
|
58
|
+
}
|
|
59
|
+
return new TransactionBuilder(this._program.api, this._program.registry, 'send_message', ['Transfer', to, value], '(String, ActorId, U256)', 'bool', this._program.programId);
|
|
48
60
|
}
|
|
49
61
|
async allowance(owner, spender, originAddress, value, atBlock) {
|
|
50
|
-
const payload = this.registry.createType('(String, ActorId, ActorId)', ['Allowance', owner, spender]).
|
|
51
|
-
const reply = await this.api.message.calculateReply({
|
|
52
|
-
destination: this.programId,
|
|
62
|
+
const payload = this._program.registry.createType('(String, ActorId, ActorId)', ['Allowance', owner, spender]).toHex();
|
|
63
|
+
const reply = await this._program.api.message.calculateReply({
|
|
64
|
+
destination: this._program.programId,
|
|
53
65
|
origin: decodeAddress(originAddress),
|
|
54
66
|
payload,
|
|
55
67
|
value: value || 0,
|
|
56
|
-
gasLimit: this.api.blockGasLimit.toBigInt(),
|
|
68
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
57
69
|
at: atBlock
|
|
58
70
|
});
|
|
59
|
-
const result = this.registry.createType('(String, U256)', reply.payload);
|
|
71
|
+
const result = this._program.registry.createType('(String, U256)', reply.payload);
|
|
60
72
|
return result[1].toBigInt();
|
|
61
73
|
}
|
|
62
74
|
async balanceOf(owner, originAddress, value, atBlock) {
|
|
63
|
-
const payload = this.registry.createType('(String, ActorId)', ['BalanceOf', owner]).
|
|
64
|
-
const reply = await this.api.message.calculateReply({
|
|
65
|
-
destination: this.programId,
|
|
75
|
+
const payload = this._program.registry.createType('(String, ActorId)', ['BalanceOf', owner]).toHex();
|
|
76
|
+
const reply = await this._program.api.message.calculateReply({
|
|
77
|
+
destination: this._program.programId,
|
|
66
78
|
origin: decodeAddress(originAddress),
|
|
67
79
|
payload,
|
|
68
80
|
value: value || 0,
|
|
69
|
-
gasLimit: this.api.blockGasLimit.toBigInt(),
|
|
81
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
70
82
|
at: atBlock
|
|
71
83
|
});
|
|
72
|
-
const result = this.registry.createType('(String, U256)', reply.payload);
|
|
84
|
+
const result = this._program.registry.createType('(String, U256)', reply.payload);
|
|
73
85
|
return result[1].toBigInt();
|
|
74
86
|
}
|
|
75
87
|
async decimals(originAddress, value, atBlock) {
|
|
76
|
-
const payload = this.registry.createType('String', 'Decimals').
|
|
77
|
-
const reply = await this.api.message.calculateReply({
|
|
78
|
-
destination: this.programId,
|
|
88
|
+
const payload = this._program.registry.createType('String', 'Decimals').toHex();
|
|
89
|
+
const reply = await this._program.api.message.calculateReply({
|
|
90
|
+
destination: this._program.programId,
|
|
79
91
|
origin: decodeAddress(originAddress),
|
|
80
92
|
payload,
|
|
81
93
|
value: value || 0,
|
|
82
|
-
gasLimit: this.api.blockGasLimit.toBigInt(),
|
|
94
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
83
95
|
at: atBlock
|
|
84
96
|
});
|
|
85
|
-
const result = this.registry.createType('(String, u8)', reply.payload);
|
|
97
|
+
const result = this._program.registry.createType('(String, u8)', reply.payload);
|
|
86
98
|
return result[1].toNumber();
|
|
87
99
|
}
|
|
88
100
|
async name(originAddress, value, atBlock) {
|
|
89
|
-
const payload = this.registry.createType('String', 'Name').
|
|
90
|
-
const reply = await this.api.message.calculateReply({
|
|
91
|
-
destination: this.programId,
|
|
101
|
+
const payload = this._program.registry.createType('String', 'Name').toHex();
|
|
102
|
+
const reply = await this._program.api.message.calculateReply({
|
|
103
|
+
destination: this._program.programId,
|
|
92
104
|
origin: decodeAddress(originAddress),
|
|
93
105
|
payload,
|
|
94
106
|
value: value || 0,
|
|
95
|
-
gasLimit: this.api.blockGasLimit.toBigInt(),
|
|
107
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
96
108
|
at: atBlock
|
|
97
109
|
});
|
|
98
|
-
const result = this.registry.createType('(String, String)', reply.payload);
|
|
110
|
+
const result = this._program.registry.createType('(String, String)', reply.payload);
|
|
99
111
|
return result[1].toString();
|
|
100
112
|
}
|
|
101
113
|
async symbol(originAddress, value, atBlock) {
|
|
102
|
-
const payload = this.registry.createType('String', 'Symbol').
|
|
103
|
-
const reply = await this.api.message.calculateReply({
|
|
104
|
-
destination: this.programId,
|
|
114
|
+
const payload = this._program.registry.createType('String', 'Symbol').toHex();
|
|
115
|
+
const reply = await this._program.api.message.calculateReply({
|
|
116
|
+
destination: this._program.programId,
|
|
105
117
|
origin: decodeAddress(originAddress),
|
|
106
118
|
payload,
|
|
107
119
|
value: value || 0,
|
|
108
|
-
gasLimit: this.api.blockGasLimit.toBigInt(),
|
|
120
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
109
121
|
at: atBlock
|
|
110
122
|
});
|
|
111
|
-
const result = this.registry.createType('(String, String)', reply.payload);
|
|
123
|
+
const result = this._program.registry.createType('(String, String)', reply.payload);
|
|
112
124
|
return result[1].toString();
|
|
113
125
|
}
|
|
114
126
|
async totalSupply(originAddress, value, atBlock) {
|
|
115
|
-
const payload = this.registry.createType('String', 'TotalSupply').
|
|
116
|
-
const reply = await this.api.message.calculateReply({
|
|
117
|
-
destination: this.programId,
|
|
127
|
+
const payload = this._program.registry.createType('String', 'TotalSupply').toHex();
|
|
128
|
+
const reply = await this._program.api.message.calculateReply({
|
|
129
|
+
destination: this._program.programId,
|
|
118
130
|
origin: decodeAddress(originAddress),
|
|
119
131
|
payload,
|
|
120
132
|
value: value || 0,
|
|
121
|
-
gasLimit: this.api.blockGasLimit.toBigInt(),
|
|
133
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
122
134
|
at: atBlock
|
|
123
135
|
});
|
|
124
|
-
const result = this.registry.createType('(String, U256)', reply.payload);
|
|
136
|
+
const result = this._program.registry.createType('(String, U256)', reply.payload);
|
|
125
137
|
return result[1].toBigInt();
|
|
126
138
|
}
|
|
127
|
-
}
|
|
128
|
-
export function getGRC20ContractPromise(apiPromise, contractAddress) {
|
|
129
|
-
const gearApi = apiPromise;
|
|
130
|
-
return new GRC20(gearApi, contractAddress);
|
|
131
139
|
}
|
package/utils/gear/index.d.ts
CHANGED
package/utils/gear/index.js
CHANGED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { GearApi } from '@gear-js/api';
|
|
3
|
+
import { ActorId, TransactionBuilder } from 'sails-js';
|
|
4
|
+
import { TypeRegistry } from '@polkadot/types';
|
|
5
|
+
export declare class VFT {
|
|
6
|
+
api: GearApi;
|
|
7
|
+
programId: `0x${string}`;
|
|
8
|
+
readonly registry: TypeRegistry;
|
|
9
|
+
readonly service: VftService;
|
|
10
|
+
constructor(api: GearApi, programId?: `0x${string}`);
|
|
11
|
+
newCtorFromCode(code: Uint8Array | Buffer, name: string, symbol: string, decimals: number): TransactionBuilder<null>;
|
|
12
|
+
newCtorFromCodeId(codeId: `0x${string}`, name: string, symbol: string, decimals: number): TransactionBuilder<null>;
|
|
13
|
+
}
|
|
14
|
+
export declare class VftService {
|
|
15
|
+
private _program;
|
|
16
|
+
constructor(_program: VFT);
|
|
17
|
+
approve(spender: ActorId, value: number | string | bigint): TransactionBuilder<boolean>;
|
|
18
|
+
transfer(to: ActorId, value: number | string | bigint): TransactionBuilder<boolean>;
|
|
19
|
+
transferFrom(from: ActorId, to: ActorId, value: number | string | bigint): TransactionBuilder<boolean>;
|
|
20
|
+
allowance(owner: ActorId, spender: ActorId, originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<bigint>;
|
|
21
|
+
balanceOf(account: ActorId, originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<bigint>;
|
|
22
|
+
decimals(originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<number>;
|
|
23
|
+
name(originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<string>;
|
|
24
|
+
symbol(originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<string>;
|
|
25
|
+
totalSupply(originAddress: string, value?: number | string | bigint, atBlock?: `0x${string}`): Promise<bigint>;
|
|
26
|
+
subscribeToApprovalEvent(callback: (data: {
|
|
27
|
+
owner: ActorId;
|
|
28
|
+
spender: ActorId;
|
|
29
|
+
value: number | string | bigint;
|
|
30
|
+
}) => void | Promise<void>): Promise<() => void>;
|
|
31
|
+
subscribeToTransferEvent(callback: (data: {
|
|
32
|
+
from: ActorId;
|
|
33
|
+
to: ActorId;
|
|
34
|
+
value: number | string | bigint;
|
|
35
|
+
}) => void | Promise<void>): Promise<() => void>;
|
|
36
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { decodeAddress } from '@gear-js/api';
|
|
5
|
+
import { getFnNamePrefix, getServiceNamePrefix, TransactionBuilder, ZERO_ADDRESS } from 'sails-js';
|
|
6
|
+
import { TypeRegistry } from '@polkadot/types';
|
|
7
|
+
export class VFT {
|
|
8
|
+
constructor(api, programId = '0x') {
|
|
9
|
+
this.api = api;
|
|
10
|
+
this.programId = programId;
|
|
11
|
+
const types = {};
|
|
12
|
+
this.registry = new TypeRegistry();
|
|
13
|
+
this.registry.setKnownTypes({
|
|
14
|
+
types
|
|
15
|
+
});
|
|
16
|
+
this.registry.register(types);
|
|
17
|
+
this.service = new VftService(this);
|
|
18
|
+
}
|
|
19
|
+
newCtorFromCode(code, name, symbol, decimals) {
|
|
20
|
+
const builder = new TransactionBuilder(this.api, this.registry, 'upload_program', ['New', name, symbol, decimals], '(String, String, String, u8)', 'String', code);
|
|
21
|
+
this.programId = builder.programId;
|
|
22
|
+
return builder;
|
|
23
|
+
}
|
|
24
|
+
newCtorFromCodeId(codeId, name, symbol, decimals) {
|
|
25
|
+
const builder = new TransactionBuilder(this.api, this.registry, 'create_program', ['New', name, symbol, decimals], '(String, String, String, u8)', 'String', codeId);
|
|
26
|
+
this.programId = builder.programId;
|
|
27
|
+
return builder;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class VftService {
|
|
31
|
+
constructor(_program) {
|
|
32
|
+
this._program = _program;
|
|
33
|
+
}
|
|
34
|
+
approve(spender, value) {
|
|
35
|
+
if (!this._program.programId) {
|
|
36
|
+
throw new Error('Program ID is not set');
|
|
37
|
+
}
|
|
38
|
+
return new TransactionBuilder(this._program.api, this._program.registry, 'send_message', ['Vft', 'Approve', spender, value], '(String, String, [u8;32], U256)', 'bool', this._program.programId);
|
|
39
|
+
}
|
|
40
|
+
transfer(to, value) {
|
|
41
|
+
if (!this._program.programId) {
|
|
42
|
+
throw new Error('Program ID is not set');
|
|
43
|
+
}
|
|
44
|
+
return new TransactionBuilder(this._program.api, this._program.registry, 'send_message', ['Vft', 'Transfer', to, value], '(String, String, [u8;32], U256)', 'bool', this._program.programId);
|
|
45
|
+
}
|
|
46
|
+
transferFrom(from, to, value) {
|
|
47
|
+
if (!this._program.programId) {
|
|
48
|
+
throw new Error('Program ID is not set');
|
|
49
|
+
}
|
|
50
|
+
return new 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);
|
|
51
|
+
}
|
|
52
|
+
async allowance(owner, spender, originAddress, value, atBlock) {
|
|
53
|
+
const payload = this._program.registry.createType('(String, String, [u8;32], [u8;32])', ['Vft', 'Allowance', owner, spender]).toHex();
|
|
54
|
+
const reply = await this._program.api.message.calculateReply({
|
|
55
|
+
destination: this._program.programId,
|
|
56
|
+
origin: decodeAddress(originAddress),
|
|
57
|
+
payload,
|
|
58
|
+
value: value || 0,
|
|
59
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
60
|
+
at: atBlock
|
|
61
|
+
});
|
|
62
|
+
const result = this._program.registry.createType('(String, String, U256)', reply.payload);
|
|
63
|
+
return result[2].toBigInt();
|
|
64
|
+
}
|
|
65
|
+
async balanceOf(account, originAddress, value, atBlock) {
|
|
66
|
+
const payload = this._program.registry.createType('(String, String, [u8;32])', ['Vft', 'BalanceOf', account]).toHex();
|
|
67
|
+
const reply = await this._program.api.message.calculateReply({
|
|
68
|
+
destination: this._program.programId,
|
|
69
|
+
origin: decodeAddress(originAddress),
|
|
70
|
+
payload,
|
|
71
|
+
value: value || 0,
|
|
72
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
73
|
+
at: atBlock
|
|
74
|
+
});
|
|
75
|
+
const result = this._program.registry.createType('(String, String, U256)', reply.payload);
|
|
76
|
+
return result[2].toBigInt();
|
|
77
|
+
}
|
|
78
|
+
async decimals(originAddress, value, atBlock) {
|
|
79
|
+
const payload = this._program.registry.createType('(String, String)', ['Vft', 'Decimals']).toHex();
|
|
80
|
+
const reply = await this._program.api.message.calculateReply({
|
|
81
|
+
destination: this._program.programId,
|
|
82
|
+
origin: decodeAddress(originAddress),
|
|
83
|
+
payload,
|
|
84
|
+
value: value || 0,
|
|
85
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
86
|
+
at: atBlock
|
|
87
|
+
});
|
|
88
|
+
const result = this._program.registry.createType('(String, String, u8)', reply.payload);
|
|
89
|
+
return result[2].toNumber();
|
|
90
|
+
}
|
|
91
|
+
async name(originAddress, value, atBlock) {
|
|
92
|
+
const payload = this._program.registry.createType('(String, String)', ['Vft', 'Name']).toHex();
|
|
93
|
+
const reply = await this._program.api.message.calculateReply({
|
|
94
|
+
destination: this._program.programId,
|
|
95
|
+
origin: decodeAddress(originAddress),
|
|
96
|
+
payload,
|
|
97
|
+
value: value || 0,
|
|
98
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
99
|
+
at: atBlock
|
|
100
|
+
});
|
|
101
|
+
const result = this._program.registry.createType('(String, String, String)', reply.payload);
|
|
102
|
+
return result[2].toString();
|
|
103
|
+
}
|
|
104
|
+
async symbol(originAddress, value, atBlock) {
|
|
105
|
+
const payload = this._program.registry.createType('(String, String)', ['Vft', 'Symbol']).toHex();
|
|
106
|
+
const reply = await this._program.api.message.calculateReply({
|
|
107
|
+
destination: this._program.programId,
|
|
108
|
+
origin: decodeAddress(originAddress),
|
|
109
|
+
payload,
|
|
110
|
+
value: value || 0,
|
|
111
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
112
|
+
at: atBlock
|
|
113
|
+
});
|
|
114
|
+
const result = this._program.registry.createType('(String, String, String)', reply.payload);
|
|
115
|
+
return result[2].toString();
|
|
116
|
+
}
|
|
117
|
+
async totalSupply(originAddress, value, atBlock) {
|
|
118
|
+
const payload = this._program.registry.createType('(String, String)', ['Vft', 'TotalSupply']).toHex();
|
|
119
|
+
const reply = await this._program.api.message.calculateReply({
|
|
120
|
+
destination: this._program.programId,
|
|
121
|
+
origin: decodeAddress(originAddress),
|
|
122
|
+
payload,
|
|
123
|
+
value: value || 0,
|
|
124
|
+
gasLimit: this._program.api.blockGasLimit.toBigInt(),
|
|
125
|
+
at: atBlock
|
|
126
|
+
});
|
|
127
|
+
const result = this._program.registry.createType('(String, String, U256)', reply.payload);
|
|
128
|
+
return result[2].toBigInt();
|
|
129
|
+
}
|
|
130
|
+
subscribeToApprovalEvent(callback) {
|
|
131
|
+
return this._program.api.gearEvents.subscribeToGearEvent('UserMessageSent', ({
|
|
132
|
+
data: {
|
|
133
|
+
message
|
|
134
|
+
}
|
|
135
|
+
}) => {
|
|
136
|
+
if (!message.source.eq(this._program.programId) || !message.destination.eq(ZERO_ADDRESS)) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const payload = message.payload.toHex();
|
|
140
|
+
if (getServiceNamePrefix(payload) === 'Vft' && getFnNamePrefix(payload) === 'Approval') {
|
|
141
|
+
// eslint-disable-next-line node/no-callback-literal,@typescript-eslint/no-floating-promises
|
|
142
|
+
callback(this._program.registry.createType('(String, String, {"owner":"[u8;32]","spender":"[u8;32]","value":"U256"})', message.payload)[2].toJSON());
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
subscribeToTransferEvent(callback) {
|
|
147
|
+
return this._program.api.gearEvents.subscribeToGearEvent('UserMessageSent', ({
|
|
148
|
+
data: {
|
|
149
|
+
message
|
|
150
|
+
}
|
|
151
|
+
}) => {
|
|
152
|
+
if (!message.source.eq(this._program.programId) || !message.destination.eq(ZERO_ADDRESS)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const payload = message.payload.toHex();
|
|
156
|
+
if (getServiceNamePrefix(payload) === 'Service' && getFnNamePrefix(payload) === 'Transfer') {
|
|
157
|
+
// eslint-disable-next-line node/no-callback-literal,@typescript-eslint/no-floating-promises
|
|
158
|
+
callback(this._program.registry.createType('(String, String, {"from":"[u8;32]","to":"[u8;32]","value":"U256"})', message.payload)[2].toJSON());
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
package/utils/metadata.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
2
|
+
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
3
|
+
import { HexString } from '@polkadot/util/types';
|
|
4
|
+
import { ExtraInfo } from '@polkadot-api/merkleize-metadata';
|
|
1
5
|
export declare const _isRuntimeUpdated: (signedExtensions?: string[]) => boolean;
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const getShortMetadata: (
|
|
6
|
+
export declare const calculateMetadataHash: (extraInfo: ExtraInfo, metadataV15: HexString) => string;
|
|
7
|
+
export declare const getShortMetadata: (blob: HexString, extraInfo: ExtraInfo, metadata: HexString) => string;
|
|
8
|
+
export declare const cacheMetadata: (chain: string, substrateApi: _SubstrateApi, chainService?: ChainService) => void;
|
package/utils/metadata.js
CHANGED
|
@@ -1,39 +1,49 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import { getSpecExtensions, getSpecTypes } from '@polkadot/types-known';
|
|
5
|
+
import { u8aToHex } from '@polkadot/util';
|
|
6
|
+
import { merkleizeMetadata } from '@polkadot-api/merkleize-metadata';
|
|
6
7
|
export const _isRuntimeUpdated = signedExtensions => {
|
|
7
8
|
return signedExtensions ? signedExtensions.includes('CheckMetadataHash') : false;
|
|
8
9
|
};
|
|
9
|
-
export const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
};
|
|
13
|
-
const resp = await fetch(createUrl('node/metadata/hash'), {
|
|
14
|
-
method: 'POST',
|
|
15
|
-
headers: {
|
|
16
|
-
'Content-Type': 'application/json'
|
|
17
|
-
},
|
|
18
|
-
body: JSON.stringify(data)
|
|
19
|
-
});
|
|
20
|
-
const rs = await resp.json();
|
|
21
|
-
return rs.metadataHash;
|
|
10
|
+
export const calculateMetadataHash = (extraInfo, metadataV15) => {
|
|
11
|
+
const _merkleizeMetadata = merkleizeMetadata(metadataV15, extraInfo);
|
|
12
|
+
return u8aToHex(_merkleizeMetadata.digest());
|
|
22
13
|
};
|
|
23
|
-
export const getShortMetadata =
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
14
|
+
export const getShortMetadata = (blob, extraInfo, metadata) => {
|
|
15
|
+
const _merkleizeMetadata = merkleizeMetadata(metadata, extraInfo);
|
|
16
|
+
return u8aToHex(_merkleizeMetadata.getProofForExtrinsicPayload(blob));
|
|
17
|
+
};
|
|
18
|
+
export const cacheMetadata = (chain, substrateApi, chainService) => {
|
|
19
|
+
// Update metadata to database with async methods
|
|
20
|
+
substrateApi.api.isReady.then(async api => {
|
|
21
|
+
const currentSpecVersion = api.runtimeVersion.specVersion.toString();
|
|
22
|
+
const specName = api.runtimeVersion.specName.toString();
|
|
23
|
+
const genesisHash = api.genesisHash.toHex();
|
|
24
|
+
const metadata = await (chainService === null || chainService === void 0 ? void 0 : chainService.getMetadata(chain));
|
|
25
|
+
|
|
26
|
+
// Avoid date existed metadata
|
|
27
|
+
if (metadata && metadata.specVersion === currentSpecVersion && metadata.genesisHash === genesisHash) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const systemChain = await api.rpc.system.chain();
|
|
31
|
+
// const _metadata: Option<OpaqueMetadata> = await api.call.metadata.metadataAtVersion(15);
|
|
32
|
+
// const metadataHex = _metadata.isSome ? _metadata.unwrap().toHex().slice(2) : ''; // Need unwrap to create metadata object
|
|
33
|
+
let hexV15;
|
|
34
|
+
const metadataV15 = await api.call.metadata.metadataAtVersion(15);
|
|
35
|
+
if (!metadataV15.isEmpty) {
|
|
36
|
+
hexV15 = metadataV15.unwrap().toHex();
|
|
37
|
+
}
|
|
38
|
+
chainService === null || chainService === void 0 ? void 0 : chainService.upsertMetadata(chain, {
|
|
39
|
+
chain: chain,
|
|
40
|
+
genesisHash: genesisHash,
|
|
41
|
+
specName: specName,
|
|
42
|
+
specVersion: currentSpecVersion,
|
|
43
|
+
hexValue: api.runtimeMetadata.toHex(),
|
|
44
|
+
types: getSpecTypes(api.registry, systemChain, api.runtimeVersion.specName, api.runtimeVersion.specVersion),
|
|
45
|
+
userExtensions: getSpecExtensions(api.registry, systemChain, api.runtimeVersion.specName),
|
|
46
|
+
hexV15
|
|
47
|
+
}).catch(console.error);
|
|
48
|
+
}).catch(console.error);
|
|
39
49
|
};
|