@subwallet/extension-base 1.3.46-0 → 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.
- package/cjs/koni/api/nft/ordinal_nft/index.js +3 -2
- package/cjs/koni/background/handlers/State.js +3 -0
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +8 -14
- package/cjs/services/buy-service/index.js +2 -0
- package/cjs/services/chain-service/utils/index.js +3 -0
- package/cjs/services/chain-service/utils/patch.js +1 -1
- package/cjs/services/earning-service/handlers/native-staking/amplitude.js +32 -0
- package/cjs/services/earning-service/handlers/native-staking/astar.js +18 -0
- package/cjs/services/earning-service/handlers/native-staking/base.js +37 -29
- package/cjs/services/earning-service/handlers/native-staking/dtao.js +5 -0
- package/cjs/services/earning-service/handlers/native-staking/mythos.js +28 -0
- package/cjs/services/earning-service/handlers/native-staking/para-chain.js +17 -0
- package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +16 -0
- package/cjs/services/earning-service/handlers/native-staking/tao.js +5 -0
- package/cjs/services/earning-service/service.js +26 -5
- package/cjs/services/history-service/index.js +12 -7
- package/cjs/services/subscan-service/index.js +35 -104
- package/cjs/services/transaction-service/utils.js +10 -1
- package/cjs/strategy/api-request-strategy/index.js +1 -0
- package/cjs/strategy/api-request-strategy/utils/index.js +2 -2
- package/cjs/strategy/api-request-strategy-v2/index.js +138 -0
- package/cjs/strategy/api-request-strategy-v2/types.js +1 -0
- package/cjs/utils/gear/combine.js +4 -3
- package/cjs/utils/gear/vft.js +104 -135
- package/koni/api/nft/ordinal_nft/index.js +3 -2
- package/koni/background/handlers/State.js +4 -1
- package/package.json +20 -9
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/subscribe/substrate/index.js +8 -14
- package/services/buy-service/index.js +2 -0
- package/services/chain-service/utils/index.js +3 -0
- package/services/chain-service/utils/patch.js +1 -1
- package/services/earning-service/handlers/native-staking/amplitude.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/amplitude.js +32 -0
- package/services/earning-service/handlers/native-staking/astar.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/astar.js +18 -0
- package/services/earning-service/handlers/native-staking/base.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/base.js +37 -29
- package/services/earning-service/handlers/native-staking/dtao.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/dtao.js +5 -0
- package/services/earning-service/handlers/native-staking/mythos.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/mythos.js +28 -0
- package/services/earning-service/handlers/native-staking/para-chain.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/para-chain.js +17 -0
- package/services/earning-service/handlers/native-staking/relay-chain.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/relay-chain.js +16 -0
- package/services/earning-service/handlers/native-staking/tao.d.ts +1 -0
- package/services/earning-service/handlers/native-staking/tao.js +5 -0
- package/services/earning-service/service.d.ts +1 -0
- package/services/earning-service/service.js +26 -5
- package/services/history-service/index.js +12 -7
- package/services/subscan-service/index.d.ts +13 -27
- package/services/subscan-service/index.js +26 -95
- package/services/transaction-service/utils.js +11 -2
- package/strategy/api-request-strategy/context/base.d.ts +2 -6
- package/strategy/api-request-strategy/index.js +1 -0
- package/strategy/api-request-strategy/types.d.ts +4 -2
- package/strategy/api-request-strategy/utils/index.js +2 -2
- package/strategy/api-request-strategy-v2/index.d.ts +22 -0
- package/strategy/api-request-strategy-v2/index.js +128 -0
- package/strategy/api-request-strategy-v2/types.d.ts +11 -0
- package/strategy/api-request-strategy-v2/types.js +1 -0
- package/types/buy.d.ts +1 -1
- package/utils/gear/combine.d.ts +2 -1
- package/utils/gear/combine.js +4 -4
- package/utils/gear/vft.d.ts +20 -9
- package/utils/gear/vft.js +104 -135
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { SWError } from '@subwallet/extension-base/background/errors/SWError';
|
|
5
|
+
import { BASE_MINUTE_INTERVAL } from '@subwallet/extension-base/constants';
|
|
6
|
+
import { Md5 } from 'ts-md5';
|
|
7
|
+
export class BaseApiRequestStrategyV2 {
|
|
8
|
+
nextId = 0;
|
|
9
|
+
groupId = 0;
|
|
10
|
+
isRunning = false;
|
|
11
|
+
requestMap = {};
|
|
12
|
+
processInterval = undefined;
|
|
13
|
+
canceledGroupIds = new Set();
|
|
14
|
+
cacheMap = new Map();
|
|
15
|
+
getId() {
|
|
16
|
+
return this.nextId++;
|
|
17
|
+
}
|
|
18
|
+
constructor(context) {
|
|
19
|
+
this.context = context;
|
|
20
|
+
}
|
|
21
|
+
getGroupId() {
|
|
22
|
+
return this.groupId++;
|
|
23
|
+
}
|
|
24
|
+
createKeyHash(keys) {
|
|
25
|
+
return Md5.hashStr(JSON.stringify([this.constructor.name, ...keys]));
|
|
26
|
+
}
|
|
27
|
+
addRequest(run, ordinal, _groupId, keyHash) {
|
|
28
|
+
const newId = this.getId();
|
|
29
|
+
const groupId = _groupId !== null && _groupId !== void 0 ? _groupId : this.getGroupId();
|
|
30
|
+
if (this.canceledGroupIds.has(groupId)) {
|
|
31
|
+
return Promise.reject(new SWError('CANCELED', 'Request has been canceled'));
|
|
32
|
+
}
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
this.requestMap[newId] = {
|
|
35
|
+
cacheKey: keyHash,
|
|
36
|
+
groupId,
|
|
37
|
+
id: newId,
|
|
38
|
+
ordinal,
|
|
39
|
+
reject,
|
|
40
|
+
resolve,
|
|
41
|
+
retry: -1,
|
|
42
|
+
run,
|
|
43
|
+
status: 'pending'
|
|
44
|
+
};
|
|
45
|
+
if (!this.isRunning) {
|
|
46
|
+
this.process();
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
process() {
|
|
51
|
+
this.stop();
|
|
52
|
+
this.isRunning = true;
|
|
53
|
+
const maxRetry = this.context.maxRetry;
|
|
54
|
+
const interval = setInterval(() => {
|
|
55
|
+
const remainingRequests = Object.values(this.requestMap);
|
|
56
|
+
if (remainingRequests.length === 0) {
|
|
57
|
+
this.isRunning = false;
|
|
58
|
+
clearInterval(interval);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
console.log('[ApiRequestStrategyV2] Processing requests...', remainingRequests.map(r => r.groupId));
|
|
62
|
+
|
|
63
|
+
// Get first this.limit requests base on id
|
|
64
|
+
const requests = remainingRequests.filter(request => request.status !== 'running').sort((a, b) => a.id - b.id).sort((a, b) => a.ordinal - b.ordinal).slice(0, this.context.callRate);
|
|
65
|
+
|
|
66
|
+
// Start requests
|
|
67
|
+
requests.forEach(request => {
|
|
68
|
+
request.status = 'running';
|
|
69
|
+
if (request.cacheKey) {
|
|
70
|
+
if (this.cacheMap.has(request.cacheKey)) {
|
|
71
|
+
const resp = this.cacheMap.get(request.cacheKey);
|
|
72
|
+
request.resolve(resp);
|
|
73
|
+
console.log('[ApiRequestStrategyV2] Cache hit for request', request.id, 'with cache key', request.cacheKey);
|
|
74
|
+
delete this.requestMap[request.id];
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
request.run().then(rs => {
|
|
79
|
+
request.resolve(rs);
|
|
80
|
+
if (request.cacheKey) {
|
|
81
|
+
this.cacheMap.set(request.cacheKey, rs);
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
if (request.cacheKey) {
|
|
84
|
+
this.cacheMap.delete(request.cacheKey);
|
|
85
|
+
}
|
|
86
|
+
}, BASE_MINUTE_INTERVAL);
|
|
87
|
+
}
|
|
88
|
+
delete this.requestMap[request.id];
|
|
89
|
+
}).catch(e => {
|
|
90
|
+
const isRateLimited = this.isRateLimited(e);
|
|
91
|
+
|
|
92
|
+
// Limit rate
|
|
93
|
+
if (isRateLimited) {
|
|
94
|
+
if (request.retry < maxRetry) {
|
|
95
|
+
request.status = 'pending';
|
|
96
|
+
request.retry++;
|
|
97
|
+
this.context.reduceLimitRate();
|
|
98
|
+
} else {
|
|
99
|
+
// Reject request
|
|
100
|
+
request.reject(new SWError('MAX_RETRY', String(e)));
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
request.reject(new SWError('UNKNOWN', String(e)));
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}, this.context.intervalCheck);
|
|
108
|
+
this.processInterval = interval;
|
|
109
|
+
}
|
|
110
|
+
stop() {
|
|
111
|
+
clearInterval(this.processInterval);
|
|
112
|
+
this.processInterval = undefined;
|
|
113
|
+
}
|
|
114
|
+
cancelGroupRequest(groupId) {
|
|
115
|
+
Object.values(this.requestMap).forEach(request => {
|
|
116
|
+
if (request.groupId === groupId) {
|
|
117
|
+
request.reject(new SWError('CANCELED', 'Request has been canceled'));
|
|
118
|
+
}
|
|
119
|
+
this.canceledGroupIds.add(groupId);
|
|
120
|
+
});
|
|
121
|
+
this.requestMap = Object.fromEntries(Object.entries(this.requestMap).filter(([_, request]) => request.groupId !== groupId));
|
|
122
|
+
}
|
|
123
|
+
setContext(context) {
|
|
124
|
+
this.stop();
|
|
125
|
+
this.context = context;
|
|
126
|
+
this.process();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ApiRequest, ApiRequestContext } from '../api-request-strategy/types';
|
|
2
|
+
export interface ApiRequestStrategyV2 {
|
|
3
|
+
addRequest: <T>(run: ApiRequestV2<T>['run'], groupId: number, ordinal: number) => Promise<T>;
|
|
4
|
+
setContext: (context: ApiRequestContext) => void;
|
|
5
|
+
stop: (groupId?: number) => void;
|
|
6
|
+
cancelGroupRequest: (groupId: number) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface ApiRequestV2<T> extends ApiRequest<T> {
|
|
9
|
+
groupId: number;
|
|
10
|
+
cacheKey?: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/types/buy.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export interface BuyService {
|
|
|
4
4
|
symbol: string;
|
|
5
5
|
}
|
|
6
6
|
export declare type SupportService = 'transak' | 'banxa' | 'coinbase' | 'moonpay' | 'onramper' | 'meld';
|
|
7
|
-
export declare type OnrampAccountSupportType = 'ETHEREUM' | 'SUBSTRATE' | 'TON' | 'CARDANO';
|
|
7
|
+
export declare type OnrampAccountSupportType = 'ETHEREUM' | 'SUBSTRATE' | 'TON' | 'CARDANO' | 'BITCOIN';
|
|
8
8
|
export interface BuyTokenInfo {
|
|
9
9
|
network: string;
|
|
10
10
|
symbol: string;
|
package/utils/gear/combine.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GearApi } from '@gear-js/api';
|
|
1
2
|
import { ApiPromise } from '@polkadot/api';
|
|
2
3
|
import { GRC20 } from './grc20';
|
|
3
4
|
import { VFT } from './vft';
|
|
@@ -7,4 +8,4 @@ export declare const DEFAULT_GEAR_ADDRESS: {
|
|
|
7
8
|
};
|
|
8
9
|
export declare const GEAR_DEFAULT_ADDRESS = "5EYCAe5ijiYfAXEth5DGRKiKuVjTXQKr877tUPz6eLz2t9aG";
|
|
9
10
|
export declare function getGRC20ContractPromise(apiPromise: ApiPromise, contractAddress: string): GRC20;
|
|
10
|
-
export declare function getVFTContractPromise(
|
|
11
|
+
export declare function getVFTContractPromise(api: GearApi, contractAddress?: string): VFT;
|
package/utils/gear/combine.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { GRC20 } from "./grc20.js";
|
|
5
|
-
import { VFT } from "./vft.js";
|
|
5
|
+
import { sailsCache, VFT } from "./vft.js";
|
|
6
6
|
export const DEFAULT_GEAR_ADDRESS = {
|
|
7
7
|
ALICE: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
|
|
8
8
|
BOB: '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'
|
|
@@ -12,7 +12,7 @@ export function getGRC20ContractPromise(apiPromise, contractAddress) {
|
|
|
12
12
|
const gearApi = apiPromise;
|
|
13
13
|
return new GRC20(gearApi, contractAddress);
|
|
14
14
|
}
|
|
15
|
-
export function getVFTContractPromise(
|
|
16
|
-
const
|
|
17
|
-
return new VFT(
|
|
15
|
+
export function getVFTContractPromise(api, contractAddress = '0x') {
|
|
16
|
+
const sails = sailsCache.get();
|
|
17
|
+
return new VFT(api, contractAddress, sails);
|
|
18
18
|
}
|
package/utils/gear/vft.d.ts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { GearApi } from '@gear-js/api';
|
|
3
|
-
import { ActorId, TransactionBuilder } from 'sails-js';
|
|
4
|
-
import { TypeRegistry } from '@polkadot/types';
|
|
3
|
+
import { ActorId, Sails, TransactionBuilder } from 'sails-js';
|
|
5
4
|
export declare class VFT {
|
|
6
|
-
api: GearApi;
|
|
5
|
+
readonly api: GearApi;
|
|
7
6
|
programId: `0x${string}`;
|
|
8
|
-
readonly registry: TypeRegistry;
|
|
9
7
|
readonly service: VftService;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
readonly sails: Sails;
|
|
9
|
+
constructor(api: GearApi, programId: `0x${string}`, sails: Sails);
|
|
10
|
+
newCtorFromCode(code: Uint8Array | Buffer, name: string, symbol: string, decimals: number): TransactionBuilder<any>;
|
|
11
|
+
newCtorFromCodeId(codeId: `0x${string}`, name: string, symbol: string, decimals: number): TransactionBuilder<any>;
|
|
13
12
|
}
|
|
14
13
|
export declare class VftService {
|
|
15
14
|
private _program;
|
|
16
15
|
constructor(_program: VFT);
|
|
16
|
+
private get functions();
|
|
17
|
+
private get queries();
|
|
17
18
|
approve(spender: ActorId, value: number | string | bigint): TransactionBuilder<boolean>;
|
|
18
19
|
transfer(to: ActorId, value: number | string | bigint): TransactionBuilder<boolean>;
|
|
19
20
|
transferFrom(from: ActorId, to: ActorId, value: number | string | bigint): TransactionBuilder<boolean>;
|
|
@@ -26,11 +27,21 @@ export declare class VftService {
|
|
|
26
27
|
subscribeToApprovalEvent(callback: (data: {
|
|
27
28
|
owner: ActorId;
|
|
28
29
|
spender: ActorId;
|
|
29
|
-
value:
|
|
30
|
+
value: bigint;
|
|
30
31
|
}) => void | Promise<void>): Promise<() => void>;
|
|
31
32
|
subscribeToTransferEvent(callback: (data: {
|
|
32
33
|
from: ActorId;
|
|
33
34
|
to: ActorId;
|
|
34
|
-
value:
|
|
35
|
+
value: bigint;
|
|
35
36
|
}) => void | Promise<void>): Promise<() => void>;
|
|
36
37
|
}
|
|
38
|
+
declare class SailsCache {
|
|
39
|
+
private static instance;
|
|
40
|
+
private sail;
|
|
41
|
+
private constructor();
|
|
42
|
+
static getInstance(): SailsCache;
|
|
43
|
+
init(): Promise<void>;
|
|
44
|
+
get(): Sails;
|
|
45
|
+
}
|
|
46
|
+
export declare const sailsCache: SailsCache;
|
|
47
|
+
export {};
|
package/utils/gear/vft.js
CHANGED
|
@@ -1,28 +1,26 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { TypeRegistry } from '@polkadot/types';
|
|
4
|
+
import { Sails } from 'sails-js';
|
|
5
|
+
import { SailsIdlParser } from 'sails-js-parser';
|
|
7
6
|
export class VFT {
|
|
8
|
-
constructor(api, programId = '0x') {
|
|
7
|
+
constructor(api, programId = '0x', sails) {
|
|
9
8
|
this.api = api;
|
|
10
9
|
this.programId = programId;
|
|
11
|
-
|
|
12
|
-
this.
|
|
13
|
-
this.
|
|
14
|
-
types
|
|
15
|
-
});
|
|
16
|
-
this.registry.register(types);
|
|
10
|
+
this.sails = sails;
|
|
11
|
+
this.sails.setApi(api);
|
|
12
|
+
this.sails.setProgramId(programId);
|
|
17
13
|
this.service = new VftService(this);
|
|
18
14
|
}
|
|
19
15
|
newCtorFromCode(code, name, symbol, decimals) {
|
|
20
|
-
const
|
|
16
|
+
const ctor = this.sails.ctors.New;
|
|
17
|
+
const builder = ctor.fromCode(code, name, symbol, decimals);
|
|
21
18
|
this.programId = builder.programId;
|
|
22
19
|
return builder;
|
|
23
20
|
}
|
|
24
21
|
newCtorFromCodeId(codeId, name, symbol, decimals) {
|
|
25
|
-
const
|
|
22
|
+
const ctor = this.sails.ctors.New;
|
|
23
|
+
const builder = ctor.fromCodeId(codeId, name, symbol, decimals);
|
|
26
24
|
this.programId = builder.programId;
|
|
27
25
|
return builder;
|
|
28
26
|
}
|
|
@@ -31,132 +29,103 @@ export class VftService {
|
|
|
31
29
|
constructor(_program) {
|
|
32
30
|
this._program = _program;
|
|
33
31
|
}
|
|
32
|
+
get functions() {
|
|
33
|
+
return this._program.sails.services.Vft.functions;
|
|
34
|
+
}
|
|
35
|
+
get queries() {
|
|
36
|
+
return this._program.sails.services.Vft.queries;
|
|
37
|
+
}
|
|
34
38
|
approve(spender, value) {
|
|
35
|
-
|
|
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
|
+
return this.functions.Approve(spender, value);
|
|
39
40
|
}
|
|
40
41
|
transfer(to, value) {
|
|
41
|
-
|
|
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);
|
|
42
|
+
return this.functions.Transfer(to, value);
|
|
45
43
|
}
|
|
46
44
|
transferFrom(from, to, value) {
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
return this.functions.TransferFrom(from, to, value);
|
|
46
|
+
}
|
|
47
|
+
allowance(owner, spender, originAddress, value, atBlock) {
|
|
48
|
+
return this.queries.Allowance(originAddress, BigInt(value || 0), atBlock, owner, spender);
|
|
49
|
+
}
|
|
50
|
+
balanceOf(account, originAddress, value, atBlock) {
|
|
51
|
+
return this.queries.BalanceOf(originAddress, BigInt(value || 0), atBlock, account);
|
|
52
|
+
}
|
|
53
|
+
decimals(originAddress, value, atBlock) {
|
|
54
|
+
return this.queries.Decimals(originAddress, BigInt(value || 0), atBlock);
|
|
55
|
+
}
|
|
56
|
+
name(originAddress, value, atBlock) {
|
|
57
|
+
return this.queries.Name(originAddress, BigInt(value || 0), atBlock);
|
|
58
|
+
}
|
|
59
|
+
symbol(originAddress, value, atBlock) {
|
|
60
|
+
return this.queries.Symbol(originAddress, BigInt(value || 0), atBlock);
|
|
61
|
+
}
|
|
62
|
+
totalSupply(originAddress, value, atBlock) {
|
|
63
|
+
return this.queries.TotalSupply(originAddress, BigInt(value || 0), atBlock);
|
|
64
|
+
}
|
|
65
|
+
async subscribeToApprovalEvent(callback) {
|
|
66
|
+
return this._program.sails.services.Vft.events.Approval.subscribe(callback);
|
|
67
|
+
}
|
|
68
|
+
async subscribeToTransferEvent(callback) {
|
|
69
|
+
return this._program.sails.services.Vft.events.Transfer.subscribe(callback);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Cache sai
|
|
74
|
+
const vftIdl = `
|
|
75
|
+
constructor {
|
|
76
|
+
New : (name: str, symbol: str, decimals: u8);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
service Vft {
|
|
80
|
+
Approve : (spender: actor_id, value: u256) -> bool;
|
|
81
|
+
Transfer : (to: actor_id, value: u256) -> bool;
|
|
82
|
+
TransferFrom : (from: actor_id, to: actor_id, value: u256) -> bool;
|
|
83
|
+
|
|
84
|
+
query Allowance : (owner: actor_id, spender: actor_id) -> u256;
|
|
85
|
+
query BalanceOf : (account: actor_id) -> u256;
|
|
86
|
+
query Decimals : () -> u8;
|
|
87
|
+
query Name : () -> str;
|
|
88
|
+
query Symbol : () -> str;
|
|
89
|
+
query TotalSupply : () -> u256;
|
|
90
|
+
|
|
91
|
+
events {
|
|
92
|
+
Approval: struct {
|
|
93
|
+
owner: actor_id,
|
|
94
|
+
spender: actor_id,
|
|
95
|
+
value: u256,
|
|
96
|
+
};
|
|
97
|
+
Transfer: struct {
|
|
98
|
+
from: actor_id,
|
|
99
|
+
to: actor_id,
|
|
100
|
+
value: u256,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
`;
|
|
105
|
+
class SailsCache {
|
|
106
|
+
static instance = null;
|
|
107
|
+
sail = null;
|
|
108
|
+
|
|
109
|
+
// eslint-disable-next-line no-useless-constructor, @typescript-eslint/no-empty-function
|
|
110
|
+
constructor() {}
|
|
111
|
+
static getInstance() {
|
|
112
|
+
if (!SailsCache.instance) {
|
|
113
|
+
SailsCache.instance = new SailsCache();
|
|
49
114
|
}
|
|
50
|
-
return
|
|
51
|
-
}
|
|
52
|
-
async
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
}
|
|
115
|
+
return SailsCache.instance;
|
|
116
|
+
}
|
|
117
|
+
async init() {
|
|
118
|
+
if (!this.sail) {
|
|
119
|
+
const parser = await SailsIdlParser.new();
|
|
120
|
+
const sails = new Sails(parser);
|
|
121
|
+
this.sail = sails.parseIdl(vftIdl);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
get() {
|
|
125
|
+
if (!this.sail) {
|
|
126
|
+
throw new Error('Sails is not init yet');
|
|
127
|
+
}
|
|
128
|
+
return this.sail;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export const sailsCache = SailsCache.getInstance();
|