@dedot/contracts 0.0.1-alpha.34 → 0.0.1-alpha.35
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/Contract.d.ts +2 -4
- package/Contract.js +1 -1
- package/ContractDeployer.d.ts +2 -4
- package/ContractDeployer.js +1 -2
- package/cjs/Contract.js +1 -1
- package/cjs/ContractDeployer.js +1 -2
- package/cjs/executor/ConstructorQueryExecutor.js +16 -5
- package/cjs/executor/ConstructorTxExecutor.js +5 -3
- package/cjs/executor/QueryExecutor.js +15 -14
- package/cjs/executor/TxExecutor.js +4 -3
- package/cjs/utils.js +9 -9
- package/executor/ConstructorQueryExecutor.d.ts +9 -2
- package/executor/ConstructorQueryExecutor.js +16 -5
- package/executor/ConstructorTxExecutor.d.ts +2 -2
- package/executor/ConstructorTxExecutor.js +5 -3
- package/executor/Executor.d.ts +2 -2
- package/executor/QueryExecutor.d.ts +2 -2
- package/executor/QueryExecutor.js +15 -14
- package/executor/TxExecutor.d.ts +2 -2
- package/executor/TxExecutor.js +4 -3
- package/package.json +6 -6
- package/types/index.d.ts +29 -14
- package/types/shared.d.ts +11 -16
- package/types/v4.d.ts +3 -3
- package/utils.js +9 -9
package/Contract.d.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { ISubstrateClient } from '@dedot/api';
|
|
2
|
-
import { SubstrateApi } from '@dedot/api/chaintypes';
|
|
3
2
|
import { AccountId32, AccountId32Like } from '@dedot/codecs';
|
|
4
|
-
import { GenericSubstrateApi, RpcVersion } from '@dedot/types';
|
|
5
3
|
import { TypinkRegistry } from './TypinkRegistry.js';
|
|
6
4
|
import { ContractMetadata, GenericContractApi } from './types/index.js';
|
|
7
|
-
export declare class Contract<ContractApi extends GenericContractApi = GenericContractApi
|
|
5
|
+
export declare class Contract<ContractApi extends GenericContractApi = GenericContractApi> {
|
|
8
6
|
#private;
|
|
9
|
-
constructor(api: ISubstrateClient
|
|
7
|
+
constructor(api: ISubstrateClient, metadata: ContractMetadata | string, address: AccountId32Like);
|
|
10
8
|
get metadata(): ContractMetadata;
|
|
11
9
|
get address(): AccountId32;
|
|
12
10
|
get registry(): TypinkRegistry;
|
package/Contract.js
CHANGED
package/ContractDeployer.d.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { ISubstrateClient } from '@dedot/api';
|
|
2
|
-
import { SubstrateApi } from '@dedot/api/chaintypes';
|
|
3
2
|
import { Hash } from '@dedot/codecs';
|
|
4
|
-
import { GenericSubstrateApi, RpcVersion } from '@dedot/types';
|
|
5
3
|
import { TypinkRegistry } from './TypinkRegistry.js';
|
|
6
4
|
import { ContractMetadata, GenericContractApi } from './types/index.js';
|
|
7
|
-
export declare class ContractDeployer<ContractApi extends GenericContractApi = GenericContractApi
|
|
5
|
+
export declare class ContractDeployer<ContractApi extends GenericContractApi = GenericContractApi> {
|
|
8
6
|
#private;
|
|
9
|
-
constructor(api: ISubstrateClient
|
|
7
|
+
constructor(api: ISubstrateClient, metadata: ContractMetadata | string, codeHashOrWasm: Hash | Uint8Array | string);
|
|
10
8
|
get metadata(): ContractMetadata;
|
|
11
9
|
get registry(): TypinkRegistry;
|
|
12
10
|
get tx(): ContractApi['constructorTx'];
|
package/ContractDeployer.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { TypinkRegistry } from './TypinkRegistry.js';
|
|
2
2
|
import { ConstructorQueryExecutor } from './executor/ConstructorQueryExecutor.js';
|
|
3
3
|
import { ConstructorTxExecutor } from './executor/index.js';
|
|
4
|
-
import { newProxyChain,
|
|
5
|
-
import { parseRawMetadata } from './utils.js';
|
|
4
|
+
import { ensureSupportContractsPallet, newProxyChain, parseRawMetadata } from './utils.js';
|
|
6
5
|
export class ContractDeployer {
|
|
7
6
|
#api;
|
|
8
7
|
#metadata;
|
package/cjs/Contract.js
CHANGED
|
@@ -10,7 +10,7 @@ class Contract {
|
|
|
10
10
|
#registry;
|
|
11
11
|
#address;
|
|
12
12
|
#metadata;
|
|
13
|
-
constructor(api,
|
|
13
|
+
constructor(api, metadata, address) {
|
|
14
14
|
(0, utils_js_1.ensureSupportContractsPallet)(api);
|
|
15
15
|
this.#api = api;
|
|
16
16
|
this.#address = new codecs_1.AccountId32(address);
|
package/cjs/ContractDeployer.js
CHANGED
|
@@ -5,7 +5,6 @@ const TypinkRegistry_js_1 = require("./TypinkRegistry.js");
|
|
|
5
5
|
const ConstructorQueryExecutor_js_1 = require("./executor/ConstructorQueryExecutor.js");
|
|
6
6
|
const index_js_1 = require("./executor/index.js");
|
|
7
7
|
const utils_js_1 = require("./utils.js");
|
|
8
|
-
const utils_js_2 = require("./utils.js");
|
|
9
8
|
class ContractDeployer {
|
|
10
9
|
#api;
|
|
11
10
|
#metadata;
|
|
@@ -14,7 +13,7 @@ class ContractDeployer {
|
|
|
14
13
|
constructor(api, metadata, codeHashOrWasm) {
|
|
15
14
|
(0, utils_js_1.ensureSupportContractsPallet)(api);
|
|
16
15
|
this.#api = api;
|
|
17
|
-
this.#metadata = typeof metadata === 'string' ? (0,
|
|
16
|
+
this.#metadata = typeof metadata === 'string' ? (0, utils_js_1.parseRawMetadata)(metadata) : metadata;
|
|
18
17
|
this.#registry = new TypinkRegistry_js_1.TypinkRegistry(this.#metadata);
|
|
19
18
|
this.#code = codeHashOrWasm;
|
|
20
19
|
}
|
|
@@ -2,20 +2,28 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ConstructorQueryExecutor = void 0;
|
|
4
4
|
const utils_1 = require("@dedot/utils");
|
|
5
|
-
const
|
|
6
|
-
|
|
5
|
+
const utils_js_1 = require("../utils.js");
|
|
6
|
+
const Executor_js_1 = require("./Executor.js");
|
|
7
|
+
class ConstructorQueryExecutor extends Executor_js_1.Executor {
|
|
8
|
+
code;
|
|
9
|
+
constructor(api, registry, code) {
|
|
10
|
+
super(api, registry);
|
|
11
|
+
this.code = code;
|
|
12
|
+
}
|
|
7
13
|
doExecute(constructor) {
|
|
8
|
-
const meta = this
|
|
14
|
+
const meta = this.#findConstructorMeta(constructor);
|
|
9
15
|
(0, utils_1.assert)(meta, `Constructor message not found: ${constructor}`);
|
|
10
16
|
const callFn = (...params) => {
|
|
11
|
-
// TODO verify number of arguments/params & call options presence
|
|
12
17
|
const { args } = meta;
|
|
18
|
+
(0, utils_1.assert)(params.length === args.length + 1, `Expected ${args.length + 1} arguments, got ${params.length}`);
|
|
13
19
|
const callOptions = params[args.length];
|
|
14
20
|
const { caller, value = 0n, gasLimit, storageDepositLimit, salt } = callOptions;
|
|
21
|
+
(0, utils_1.assert)(caller, 'Expected a valid caller address in ConstructorCallOptions');
|
|
22
|
+
(0, utils_1.assert)(salt, 'Expected a salt in ConstructorCallOptions');
|
|
15
23
|
const formattedInputs = args.map((arg, index) => this.tryEncode(arg, params[index]));
|
|
16
24
|
const bytes = (0, utils_1.u8aToHex)((0, utils_1.concatU8a)((0, utils_1.hexToU8a)(meta.selector), ...formattedInputs));
|
|
17
25
|
const code = {
|
|
18
|
-
|
|
26
|
+
type: (0, utils_1.isWasm)(this.code) ? 'Upload' : 'Existing',
|
|
19
27
|
value: this.code,
|
|
20
28
|
};
|
|
21
29
|
return this.api.call.contractsApi.instantiate(caller, value, gasLimit, storageDepositLimit, code, bytes, salt);
|
|
@@ -23,5 +31,8 @@ class ConstructorQueryExecutor extends ConstructorTxExecutor_js_1.ConstructorTxE
|
|
|
23
31
|
callFn.meta = meta;
|
|
24
32
|
return callFn;
|
|
25
33
|
}
|
|
34
|
+
#findConstructorMeta(constructor) {
|
|
35
|
+
return this.metadata.spec.constructors.find((one) => (0, utils_js_1.normalizeLabel)(one.label) === constructor);
|
|
36
|
+
}
|
|
26
37
|
}
|
|
27
38
|
exports.ConstructorQueryExecutor = ConstructorQueryExecutor;
|
|
@@ -11,13 +11,15 @@ class ConstructorTxExecutor extends Executor_js_1.Executor {
|
|
|
11
11
|
this.code = code;
|
|
12
12
|
}
|
|
13
13
|
doExecute(constructor) {
|
|
14
|
-
const meta = this
|
|
14
|
+
const meta = this.#findConstructorMeta(constructor);
|
|
15
15
|
(0, utils_1.assert)(meta, `Constructor message not found: ${constructor}`);
|
|
16
16
|
const callFn = (...params) => {
|
|
17
|
-
// TODO verify number of arguments/params & call options presence
|
|
18
17
|
const { args } = meta;
|
|
18
|
+
(0, utils_1.assert)(params.length === args.length + 1, `Expected ${args.length + 1} arguments, got ${params.length}`);
|
|
19
19
|
const txCallOptions = params[args.length];
|
|
20
20
|
const { value = 0n, gasLimit, storageDepositLimit, salt } = txCallOptions;
|
|
21
|
+
(0, utils_1.assert)(gasLimit, 'Expected a gas limit in ConstructorTxOptions');
|
|
22
|
+
(0, utils_1.assert)(salt, 'Expected a salt in ConstructorTxOptions');
|
|
21
23
|
const formattedInputs = args.map((arg, index) => this.tryEncode(arg, params[index]));
|
|
22
24
|
const bytes = (0, utils_1.u8aToHex)((0, utils_1.concatU8a)((0, utils_1.hexToU8a)(meta.selector), ...formattedInputs));
|
|
23
25
|
if ((0, utils_1.isWasm)(this.code)) {
|
|
@@ -30,7 +32,7 @@ class ConstructorTxExecutor extends Executor_js_1.Executor {
|
|
|
30
32
|
callFn.meta = meta;
|
|
31
33
|
return callFn;
|
|
32
34
|
}
|
|
33
|
-
findConstructorMeta(constructor) {
|
|
35
|
+
#findConstructorMeta(constructor) {
|
|
34
36
|
return this.metadata.spec.constructors.find((one) => (0, utils_js_1.normalizeLabel)(one.label) === constructor);
|
|
35
37
|
}
|
|
36
38
|
}
|
|
@@ -6,32 +6,33 @@ const utils_js_1 = require("../utils.js");
|
|
|
6
6
|
const Executor_js_1 = require("./Executor.js");
|
|
7
7
|
class QueryExecutor extends Executor_js_1.Executor {
|
|
8
8
|
doExecute(message) {
|
|
9
|
-
const meta = this
|
|
9
|
+
const meta = this.#findMessage(message);
|
|
10
10
|
(0, utils_1.assert)(meta, `Query message not found: ${message}`);
|
|
11
11
|
const callFn = async (...params) => {
|
|
12
|
-
// TODO verify number of arguments/params & call options presence
|
|
13
12
|
const { args } = meta;
|
|
13
|
+
(0, utils_1.assert)(params.length === args.length + 1, `Expected ${args.length + 1} arguments, got ${params.length}`);
|
|
14
14
|
const callOptions = params[args.length];
|
|
15
15
|
const { caller, value = 0n, gasLimit, storageDepositLimit } = callOptions;
|
|
16
|
+
(0, utils_1.assert)(caller, 'Expected a valid caller address in ContractCallOptions');
|
|
16
17
|
const formattedInputs = args.map((arg, index) => this.tryEncode(arg, params[index]));
|
|
17
18
|
const bytes = (0, utils_1.u8aToHex)((0, utils_1.concatU8a)((0, utils_1.hexToU8a)(meta.selector), ...formattedInputs));
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const raw = await this.api.call.contractsApi.call(caller, this.address, value, gasLimit, storageDepositLimit, bytes);
|
|
20
|
+
return (raw.result.isOk
|
|
21
|
+
? {
|
|
21
22
|
isOk: true,
|
|
22
|
-
data: this.tryDecode(meta,
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
data: this.tryDecode(meta, raw.result.value.data),
|
|
24
|
+
raw,
|
|
25
|
+
}
|
|
26
|
+
: {
|
|
27
|
+
isOk: false,
|
|
28
|
+
err: raw.result.err,
|
|
29
|
+
raw,
|
|
30
|
+
});
|
|
30
31
|
};
|
|
31
32
|
callFn.meta = meta;
|
|
32
33
|
return callFn;
|
|
33
34
|
}
|
|
34
|
-
findMessage(message) {
|
|
35
|
+
#findMessage(message) {
|
|
35
36
|
return this.metadata.spec.messages.find((one) => (0, utils_js_1.normalizeLabel)(one.label) === message);
|
|
36
37
|
}
|
|
37
38
|
}
|
|
@@ -6,13 +6,14 @@ const utils_js_1 = require("../utils.js");
|
|
|
6
6
|
const Executor_js_1 = require("./Executor.js");
|
|
7
7
|
class TxExecutor extends Executor_js_1.Executor {
|
|
8
8
|
doExecute(message) {
|
|
9
|
-
const meta = this
|
|
9
|
+
const meta = this.#findTxMessage(message);
|
|
10
10
|
(0, utils_1.assert)(meta, `Tx message not found: ${message}`);
|
|
11
11
|
const callFn = (...params) => {
|
|
12
|
-
// TODO verify number of arguments/params & call options presence
|
|
13
12
|
const { args } = meta;
|
|
13
|
+
(0, utils_1.assert)(params.length === args.length + 1, `Expected ${args.length + 1} arguments, got ${params.length}`);
|
|
14
14
|
const txCallOptions = params[args.length];
|
|
15
15
|
const { value = 0n, gasLimit, storageDepositLimit } = txCallOptions;
|
|
16
|
+
(0, utils_1.assert)(gasLimit, 'Expected a gas limit in ContractTxOptions');
|
|
16
17
|
const formattedInputs = args.map((arg, index) => this.tryEncode(arg, params[index]));
|
|
17
18
|
const bytes = (0, utils_1.u8aToHex)((0, utils_1.concatU8a)((0, utils_1.hexToU8a)(meta.selector), ...formattedInputs));
|
|
18
19
|
return this.api.tx.contracts.call(this.address, value, gasLimit, storageDepositLimit, bytes);
|
|
@@ -20,7 +21,7 @@ class TxExecutor extends Executor_js_1.Executor {
|
|
|
20
21
|
callFn.meta = meta;
|
|
21
22
|
return callFn;
|
|
22
23
|
}
|
|
23
|
-
findTxMessage(message) {
|
|
24
|
+
#findTxMessage(message) {
|
|
24
25
|
return this.metadata.spec.messages.find((one) => one.mutates && (0, utils_js_1.normalizeLabel)(one.label) === message);
|
|
25
26
|
}
|
|
26
27
|
}
|
package/cjs/utils.js
CHANGED
|
@@ -6,7 +6,7 @@ const extractContractTypes = (contractMetadata) => {
|
|
|
6
6
|
const { types } = contractMetadata;
|
|
7
7
|
return types.map(({ type, id }) => ({
|
|
8
8
|
id,
|
|
9
|
-
|
|
9
|
+
typeDef: (0, exports.normalizeContractTypeDef)(type.def),
|
|
10
10
|
params: [],
|
|
11
11
|
path: type?.path || [],
|
|
12
12
|
docs: [],
|
|
@@ -14,10 +14,10 @@ const extractContractTypes = (contractMetadata) => {
|
|
|
14
14
|
};
|
|
15
15
|
exports.extractContractTypes = extractContractTypes;
|
|
16
16
|
const normalizeContractTypeDef = (def) => {
|
|
17
|
-
let
|
|
17
|
+
let type;
|
|
18
18
|
let value;
|
|
19
19
|
if (def.variant) {
|
|
20
|
-
|
|
20
|
+
type = 'Enum';
|
|
21
21
|
value = {
|
|
22
22
|
members: def.variant.variants?.map((variant) => ({
|
|
23
23
|
fields: variant.fields?.map((fields) => ({ typeId: fields.type, typeName: fields.typeName })) || [],
|
|
@@ -27,19 +27,19 @@ const normalizeContractTypeDef = (def) => {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
else if (def.tuple) {
|
|
30
|
-
|
|
30
|
+
type = 'Tuple';
|
|
31
31
|
value = {
|
|
32
32
|
fields: def.tuple,
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
else if (def.sequence) {
|
|
36
|
-
|
|
36
|
+
type = 'Sequence';
|
|
37
37
|
value = {
|
|
38
38
|
typeParam: def.sequence.type,
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
else if (def.composite) {
|
|
42
|
-
|
|
42
|
+
type = 'Struct';
|
|
43
43
|
value = {
|
|
44
44
|
fields: def.composite.fields.map((one) => ({
|
|
45
45
|
typeId: one.type,
|
|
@@ -49,13 +49,13 @@ const normalizeContractTypeDef = (def) => {
|
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
else if (def.primitive) {
|
|
52
|
-
|
|
52
|
+
type = 'Primitive';
|
|
53
53
|
value = {
|
|
54
54
|
kind: def.primitive,
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
57
|
else if (def.array) {
|
|
58
|
-
|
|
58
|
+
type = 'SizedVec';
|
|
59
59
|
value = {
|
|
60
60
|
len: def.array.len,
|
|
61
61
|
typeParam: def.array.type,
|
|
@@ -64,7 +64,7 @@ const normalizeContractTypeDef = (def) => {
|
|
|
64
64
|
else {
|
|
65
65
|
throw Error(`Invalid contract type def: ${JSON.stringify(def)}`);
|
|
66
66
|
}
|
|
67
|
-
return {
|
|
67
|
+
return { type, value };
|
|
68
68
|
};
|
|
69
69
|
exports.normalizeContractTypeDef = normalizeContractTypeDef;
|
|
70
70
|
const UNSUPPORTED_VERSIONS = ['V3', 'V2', 'V1'];
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import { ISubstrateClient } from '@dedot/api';
|
|
2
|
+
import { Hash } from '@dedot/codecs';
|
|
1
3
|
import { GenericSubstrateApi } from '@dedot/types';
|
|
4
|
+
import { HexString } from '@dedot/utils';
|
|
5
|
+
import { TypinkRegistry } from '../TypinkRegistry.js';
|
|
2
6
|
import { GenericConstructorQueryCall } from '../types/index.js';
|
|
3
|
-
import {
|
|
4
|
-
export declare class ConstructorQueryExecutor<ChainApi extends GenericSubstrateApi> extends
|
|
7
|
+
import { Executor } from './Executor.js';
|
|
8
|
+
export declare class ConstructorQueryExecutor<ChainApi extends GenericSubstrateApi> extends Executor<ChainApi> {
|
|
9
|
+
#private;
|
|
10
|
+
protected readonly code: Hash | Uint8Array | HexString | string;
|
|
11
|
+
constructor(api: ISubstrateClient<ChainApi>, registry: TypinkRegistry, code: Hash | Uint8Array | string);
|
|
5
12
|
doExecute(constructor: string): GenericConstructorQueryCall<ChainApi>;
|
|
6
13
|
}
|
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
import { assert, concatU8a, hexToU8a, isWasm, u8aToHex } from '@dedot/utils';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { normalizeLabel } from '../utils.js';
|
|
3
|
+
import { Executor } from './Executor.js';
|
|
4
|
+
export class ConstructorQueryExecutor extends Executor {
|
|
5
|
+
code;
|
|
6
|
+
constructor(api, registry, code) {
|
|
7
|
+
super(api, registry);
|
|
8
|
+
this.code = code;
|
|
9
|
+
}
|
|
4
10
|
doExecute(constructor) {
|
|
5
|
-
const meta = this
|
|
11
|
+
const meta = this.#findConstructorMeta(constructor);
|
|
6
12
|
assert(meta, `Constructor message not found: ${constructor}`);
|
|
7
13
|
const callFn = (...params) => {
|
|
8
|
-
// TODO verify number of arguments/params & call options presence
|
|
9
14
|
const { args } = meta;
|
|
15
|
+
assert(params.length === args.length + 1, `Expected ${args.length + 1} arguments, got ${params.length}`);
|
|
10
16
|
const callOptions = params[args.length];
|
|
11
17
|
const { caller, value = 0n, gasLimit, storageDepositLimit, salt } = callOptions;
|
|
18
|
+
assert(caller, 'Expected a valid caller address in ConstructorCallOptions');
|
|
19
|
+
assert(salt, 'Expected a salt in ConstructorCallOptions');
|
|
12
20
|
const formattedInputs = args.map((arg, index) => this.tryEncode(arg, params[index]));
|
|
13
21
|
const bytes = u8aToHex(concatU8a(hexToU8a(meta.selector), ...formattedInputs));
|
|
14
22
|
const code = {
|
|
15
|
-
|
|
23
|
+
type: isWasm(this.code) ? 'Upload' : 'Existing',
|
|
16
24
|
value: this.code,
|
|
17
25
|
};
|
|
18
26
|
return this.api.call.contractsApi.instantiate(caller, value, gasLimit, storageDepositLimit, code, bytes, salt);
|
|
@@ -20,4 +28,7 @@ export class ConstructorQueryExecutor extends ConstructorTxExecutor {
|
|
|
20
28
|
callFn.meta = meta;
|
|
21
29
|
return callFn;
|
|
22
30
|
}
|
|
31
|
+
#findConstructorMeta(constructor) {
|
|
32
|
+
return this.metadata.spec.constructors.find((one) => normalizeLabel(one.label) === constructor);
|
|
33
|
+
}
|
|
23
34
|
}
|
|
@@ -3,11 +3,11 @@ import { Hash } from '@dedot/codecs';
|
|
|
3
3
|
import { GenericSubstrateApi } from '@dedot/types';
|
|
4
4
|
import { HexString } from '@dedot/utils';
|
|
5
5
|
import { TypinkRegistry } from '../TypinkRegistry.js';
|
|
6
|
-
import {
|
|
6
|
+
import { GenericConstructorTxCall } from '../types/index.js';
|
|
7
7
|
import { Executor } from './Executor.js';
|
|
8
8
|
export declare class ConstructorTxExecutor<ChainApi extends GenericSubstrateApi> extends Executor<ChainApi> {
|
|
9
|
+
#private;
|
|
9
10
|
protected readonly code: Hash | Uint8Array | HexString | string;
|
|
10
11
|
constructor(api: ISubstrateClient<ChainApi>, registry: TypinkRegistry, code: Hash | Uint8Array | string);
|
|
11
12
|
doExecute(constructor: string): GenericConstructorTxCall<ChainApi>;
|
|
12
|
-
protected findConstructorMeta(constructor: string): ContractConstructorMessage | undefined;
|
|
13
13
|
}
|
|
@@ -8,13 +8,15 @@ export class ConstructorTxExecutor extends Executor {
|
|
|
8
8
|
this.code = code;
|
|
9
9
|
}
|
|
10
10
|
doExecute(constructor) {
|
|
11
|
-
const meta = this
|
|
11
|
+
const meta = this.#findConstructorMeta(constructor);
|
|
12
12
|
assert(meta, `Constructor message not found: ${constructor}`);
|
|
13
13
|
const callFn = (...params) => {
|
|
14
|
-
// TODO verify number of arguments/params & call options presence
|
|
15
14
|
const { args } = meta;
|
|
15
|
+
assert(params.length === args.length + 1, `Expected ${args.length + 1} arguments, got ${params.length}`);
|
|
16
16
|
const txCallOptions = params[args.length];
|
|
17
17
|
const { value = 0n, gasLimit, storageDepositLimit, salt } = txCallOptions;
|
|
18
|
+
assert(gasLimit, 'Expected a gas limit in ConstructorTxOptions');
|
|
19
|
+
assert(salt, 'Expected a salt in ConstructorTxOptions');
|
|
18
20
|
const formattedInputs = args.map((arg, index) => this.tryEncode(arg, params[index]));
|
|
19
21
|
const bytes = u8aToHex(concatU8a(hexToU8a(meta.selector), ...formattedInputs));
|
|
20
22
|
if (isWasm(this.code)) {
|
|
@@ -27,7 +29,7 @@ export class ConstructorTxExecutor extends Executor {
|
|
|
27
29
|
callFn.meta = meta;
|
|
28
30
|
return callFn;
|
|
29
31
|
}
|
|
30
|
-
findConstructorMeta(constructor) {
|
|
32
|
+
#findConstructorMeta(constructor) {
|
|
31
33
|
return this.metadata.spec.constructors.find((one) => normalizeLabel(one.label) === constructor);
|
|
32
34
|
}
|
|
33
35
|
}
|
package/executor/Executor.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { SubstrateApi } from '@dedot/api/chaintypes';
|
|
|
3
3
|
import { AccountId32 } from '@dedot/codecs';
|
|
4
4
|
import { GenericSubstrateApi, RpcVersion } from '@dedot/types';
|
|
5
5
|
import { TypinkRegistry } from '../TypinkRegistry.js';
|
|
6
|
-
import { ContractMessageArg,
|
|
6
|
+
import { ContractMessageArg, ContractCallMessage } from '../types/index.js';
|
|
7
7
|
import { ContractMetadata } from '../types/index.js';
|
|
8
8
|
export declare abstract class Executor<ChainApi extends GenericSubstrateApi = SubstrateApi[RpcVersion]> {
|
|
9
9
|
#private;
|
|
@@ -14,5 +14,5 @@ export declare abstract class Executor<ChainApi extends GenericSubstrateApi = Su
|
|
|
14
14
|
get registry(): TypinkRegistry;
|
|
15
15
|
abstract doExecute(...paths: string[]): unknown;
|
|
16
16
|
tryEncode(param: ContractMessageArg, value: any): Uint8Array;
|
|
17
|
-
tryDecode(meta:
|
|
17
|
+
tryDecode(meta: ContractCallMessage, raw: any): unknown;
|
|
18
18
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { GenericSubstrateApi } from '@dedot/types';
|
|
2
|
-
import {
|
|
2
|
+
import { GenericContractQueryCall } from '../types/index.js';
|
|
3
3
|
import { Executor } from './Executor.js';
|
|
4
4
|
export declare class QueryExecutor<ChainApi extends GenericSubstrateApi> extends Executor<ChainApi> {
|
|
5
|
+
#private;
|
|
5
6
|
doExecute(message: string): GenericContractQueryCall<ChainApi>;
|
|
6
|
-
protected findMessage(message: string): ContractMessage | undefined;
|
|
7
7
|
}
|
|
@@ -3,32 +3,33 @@ import { normalizeLabel } from '../utils.js';
|
|
|
3
3
|
import { Executor } from './Executor.js';
|
|
4
4
|
export class QueryExecutor extends Executor {
|
|
5
5
|
doExecute(message) {
|
|
6
|
-
const meta = this
|
|
6
|
+
const meta = this.#findMessage(message);
|
|
7
7
|
assert(meta, `Query message not found: ${message}`);
|
|
8
8
|
const callFn = async (...params) => {
|
|
9
|
-
// TODO verify number of arguments/params & call options presence
|
|
10
9
|
const { args } = meta;
|
|
10
|
+
assert(params.length === args.length + 1, `Expected ${args.length + 1} arguments, got ${params.length}`);
|
|
11
11
|
const callOptions = params[args.length];
|
|
12
12
|
const { caller, value = 0n, gasLimit, storageDepositLimit } = callOptions;
|
|
13
|
+
assert(caller, 'Expected a valid caller address in ContractCallOptions');
|
|
13
14
|
const formattedInputs = args.map((arg, index) => this.tryEncode(arg, params[index]));
|
|
14
15
|
const bytes = u8aToHex(concatU8a(hexToU8a(meta.selector), ...formattedInputs));
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const raw = await this.api.call.contractsApi.call(caller, this.address, value, gasLimit, storageDepositLimit, bytes);
|
|
17
|
+
return (raw.result.isOk
|
|
18
|
+
? {
|
|
18
19
|
isOk: true,
|
|
19
|
-
data: this.tryDecode(meta,
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
data: this.tryDecode(meta, raw.result.value.data),
|
|
21
|
+
raw,
|
|
22
|
+
}
|
|
23
|
+
: {
|
|
24
|
+
isOk: false,
|
|
25
|
+
err: raw.result.err,
|
|
26
|
+
raw,
|
|
27
|
+
});
|
|
27
28
|
};
|
|
28
29
|
callFn.meta = meta;
|
|
29
30
|
return callFn;
|
|
30
31
|
}
|
|
31
|
-
findMessage(message) {
|
|
32
|
+
#findMessage(message) {
|
|
32
33
|
return this.metadata.spec.messages.find((one) => normalizeLabel(one.label) === message);
|
|
33
34
|
}
|
|
34
35
|
}
|
package/executor/TxExecutor.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { GenericSubstrateApi } from '@dedot/types';
|
|
2
|
-
import {
|
|
2
|
+
import { GenericContractTxCall } from '../types/index.js';
|
|
3
3
|
import { Executor } from './Executor.js';
|
|
4
4
|
export declare class TxExecutor<ChainApi extends GenericSubstrateApi> extends Executor<ChainApi> {
|
|
5
|
+
#private;
|
|
5
6
|
doExecute(message: string): GenericContractTxCall<ChainApi>;
|
|
6
|
-
protected findTxMessage(message: string): ContractMessage | undefined;
|
|
7
7
|
}
|
package/executor/TxExecutor.js
CHANGED
|
@@ -3,13 +3,14 @@ import { normalizeLabel } from '../utils.js';
|
|
|
3
3
|
import { Executor } from './Executor.js';
|
|
4
4
|
export class TxExecutor extends Executor {
|
|
5
5
|
doExecute(message) {
|
|
6
|
-
const meta = this
|
|
6
|
+
const meta = this.#findTxMessage(message);
|
|
7
7
|
assert(meta, `Tx message not found: ${message}`);
|
|
8
8
|
const callFn = (...params) => {
|
|
9
|
-
// TODO verify number of arguments/params & call options presence
|
|
10
9
|
const { args } = meta;
|
|
10
|
+
assert(params.length === args.length + 1, `Expected ${args.length + 1} arguments, got ${params.length}`);
|
|
11
11
|
const txCallOptions = params[args.length];
|
|
12
12
|
const { value = 0n, gasLimit, storageDepositLimit } = txCallOptions;
|
|
13
|
+
assert(gasLimit, 'Expected a gas limit in ContractTxOptions');
|
|
13
14
|
const formattedInputs = args.map((arg, index) => this.tryEncode(arg, params[index]));
|
|
14
15
|
const bytes = u8aToHex(concatU8a(hexToU8a(meta.selector), ...formattedInputs));
|
|
15
16
|
return this.api.tx.contracts.call(this.address, value, gasLimit, storageDepositLimit, bytes);
|
|
@@ -17,7 +18,7 @@ export class TxExecutor extends Executor {
|
|
|
17
18
|
callFn.meta = meta;
|
|
18
19
|
return callFn;
|
|
19
20
|
}
|
|
20
|
-
findTxMessage(message) {
|
|
21
|
+
#findTxMessage(message) {
|
|
21
22
|
return this.metadata.spec.messages.find((one) => one.mutates && normalizeLabel(one.label) === message);
|
|
22
23
|
}
|
|
23
24
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dedot/contracts",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.35",
|
|
4
4
|
"description": "Delightful ink! Contract APIs",
|
|
5
5
|
"author": "Tung Vu <tung@coongcrafts.io>",
|
|
6
6
|
"main": "./cjs/index.js",
|
|
@@ -12,17 +12,17 @@
|
|
|
12
12
|
"test": "vitest --watch=false"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@dedot/api": "0.0.1-alpha.
|
|
16
|
-
"@dedot/codecs": "0.0.1-alpha.
|
|
17
|
-
"@dedot/types": "0.0.1-alpha.
|
|
18
|
-
"@dedot/utils": "0.0.1-alpha.
|
|
15
|
+
"@dedot/api": "0.0.1-alpha.35",
|
|
16
|
+
"@dedot/codecs": "0.0.1-alpha.35",
|
|
17
|
+
"@dedot/types": "0.0.1-alpha.35",
|
|
18
|
+
"@dedot/utils": "0.0.1-alpha.35"
|
|
19
19
|
},
|
|
20
20
|
"publishConfig": {
|
|
21
21
|
"access": "public",
|
|
22
22
|
"directory": "dist"
|
|
23
23
|
},
|
|
24
24
|
"license": "Apache-2.0",
|
|
25
|
-
"gitHead": "
|
|
25
|
+
"gitHead": "bf954b82ac4c8a8e1d989c0c708a099269eb4262",
|
|
26
26
|
"module": "./index.js",
|
|
27
27
|
"types": "./index.d.ts",
|
|
28
28
|
"exports": {
|
package/types/index.d.ts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import { SubstrateApi } from '@dedot/api/chaintypes';
|
|
2
|
-
import { AccountId32Like, BytesLike, Weight } from '@dedot/codecs';
|
|
3
|
-
import { AnyFunc, AsyncMethod, GenericSubstrateApi, RpcVersion } from '@dedot/types';
|
|
4
|
-
import {
|
|
2
|
+
import { AccountId32Like, BytesLike, DispatchError, Weight } from '@dedot/codecs';
|
|
3
|
+
import { AnyFunc, AsyncMethod, GenericSubstrateApi, RpcVersion, VersionedGenericSubstrateApi } from '@dedot/types';
|
|
4
|
+
import { ContractCallMessage, ContractConstructorMessage } from './shared.js';
|
|
5
5
|
import { ContractMetadataV4 } from './v4.js';
|
|
6
6
|
import { ContractMetadataV5 } from './v5.js';
|
|
7
7
|
export * from './shared.js';
|
|
8
|
+
export type GenericContractCallResult<DecodedData, ContractResult> = ({
|
|
9
|
+
isOk: true;
|
|
10
|
+
data: DecodedData;
|
|
11
|
+
} | {
|
|
12
|
+
isOk: false;
|
|
13
|
+
err: DispatchError;
|
|
14
|
+
}) & {
|
|
15
|
+
raw: ContractResult;
|
|
16
|
+
};
|
|
17
|
+
export type ContractCallResult<ChainApi extends GenericSubstrateApi> = Awaited<ReturnType<ChainApi['call']['contractsApi']['call']>>;
|
|
18
|
+
export type ContractInstantiateResult<ChainApi extends GenericSubstrateApi> = Awaited<ReturnType<ChainApi['call']['contractsApi']['instantiate']>>;
|
|
19
|
+
export type ContractSubmittableExtrinsic<ChainApi extends GenericSubstrateApi> = ReturnType<ChainApi['tx']['contracts']['call']>;
|
|
20
|
+
export type InstantiateWithCodeSubmittableExtrinsic<ChainApi extends GenericSubstrateApi> = ReturnType<ChainApi['tx']['contracts']['instantiateWithCode']>;
|
|
21
|
+
export type InstantiateSubmittableExtrinsic<ChainApi extends GenericSubstrateApi> = ReturnType<ChainApi['tx']['contracts']['instantiate']>;
|
|
22
|
+
export type GenericInstantiateSubmittableExtrinsic<ChainApi extends GenericSubstrateApi> = InstantiateSubmittableExtrinsic<ChainApi> | InstantiateWithCodeSubmittableExtrinsic<ChainApi>;
|
|
8
23
|
export type ContractMetadata = ContractMetadataV4 | ContractMetadataV5;
|
|
9
24
|
export type CallOptions = {
|
|
10
25
|
value?: bigint;
|
|
@@ -25,16 +40,16 @@ export type ContractCallOptions = CallOptions & {
|
|
|
25
40
|
export type ContractTxOptions = CallOptions & {
|
|
26
41
|
gasLimit: Weight;
|
|
27
42
|
};
|
|
28
|
-
export type GenericContractQueryCall<
|
|
29
|
-
meta:
|
|
43
|
+
export type GenericContractQueryCall<ChainApi extends GenericSubstrateApi, F extends AsyncMethod = (...args: any[]) => Promise<GenericContractCallResult<any, ContractCallResult<ChainApi>>>> = F & {
|
|
44
|
+
meta: ContractCallMessage;
|
|
30
45
|
};
|
|
31
|
-
export type GenericContractTxCall<
|
|
32
|
-
meta:
|
|
46
|
+
export type GenericContractTxCall<ChainApi extends GenericSubstrateApi, F extends AnyFunc = (...args: any[]) => ContractSubmittableExtrinsic<ChainApi>> = F & {
|
|
47
|
+
meta: ContractCallMessage;
|
|
33
48
|
};
|
|
34
|
-
export type GenericConstructorQueryCall<
|
|
49
|
+
export type GenericConstructorQueryCall<ChainApi extends GenericSubstrateApi, F extends AsyncMethod = (...args: any[]) => Promise<ContractInstantiateResult<ChainApi>>> = F & {
|
|
35
50
|
meta: ContractConstructorMessage;
|
|
36
51
|
};
|
|
37
|
-
export type GenericConstructorTxCall<
|
|
52
|
+
export type GenericConstructorTxCall<ChainApi extends GenericSubstrateApi, F extends AnyFunc = (...args: any[]) => GenericInstantiateSubmittableExtrinsic<ChainApi>> = F & {
|
|
38
53
|
meta: ContractConstructorMessage;
|
|
39
54
|
};
|
|
40
55
|
export interface GenericContractQuery<ChainApi extends GenericSubstrateApi> {
|
|
@@ -49,9 +64,9 @@ export interface GenericConstructorQuery<ChainApi extends GenericSubstrateApi> {
|
|
|
49
64
|
export interface GenericConstructorTx<ChainApi extends GenericSubstrateApi> {
|
|
50
65
|
[method: string]: GenericConstructorTxCall<ChainApi>;
|
|
51
66
|
}
|
|
52
|
-
export interface GenericContractApi<ChainApi extends
|
|
53
|
-
query: GenericContractQuery<ChainApi>;
|
|
54
|
-
tx: GenericContractTx<ChainApi>;
|
|
55
|
-
constructorQuery: GenericConstructorQuery<ChainApi>;
|
|
56
|
-
constructorTx: GenericConstructorTx<ChainApi>;
|
|
67
|
+
export interface GenericContractApi<Rv extends RpcVersion = RpcVersion, ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> {
|
|
68
|
+
query: GenericContractQuery<ChainApi[Rv]>;
|
|
69
|
+
tx: GenericContractTx<ChainApi[Rv]>;
|
|
70
|
+
constructorQuery: GenericConstructorQuery<ChainApi[Rv]>;
|
|
71
|
+
constructorTx: GenericConstructorTx<ChainApi[Rv]>;
|
|
57
72
|
}
|
package/types/shared.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export interface ContractSource {
|
|
|
3
3
|
wasm?: string;
|
|
4
4
|
language: string;
|
|
5
5
|
compiler: string;
|
|
6
|
-
|
|
6
|
+
build_info: BuildInfo;
|
|
7
7
|
}
|
|
8
8
|
export interface ContractInformation {
|
|
9
9
|
name: string;
|
|
@@ -11,14 +11,14 @@ export interface ContractInformation {
|
|
|
11
11
|
authors: string[];
|
|
12
12
|
}
|
|
13
13
|
export interface BuildInfo {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
build_mode: string;
|
|
15
|
+
cargo_contract_version: string;
|
|
16
|
+
rust_toolchain: string;
|
|
17
|
+
wasm_opt_settings: WasmOptSettings;
|
|
18
18
|
}
|
|
19
19
|
export interface WasmOptSettings {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
keep_debug_symbols: boolean;
|
|
21
|
+
optimization_passes: string;
|
|
22
22
|
}
|
|
23
23
|
export interface ContractMessageArg {
|
|
24
24
|
label: string;
|
|
@@ -28,7 +28,7 @@ export interface ContractTypeInfo {
|
|
|
28
28
|
displayName: string[];
|
|
29
29
|
type: number;
|
|
30
30
|
}
|
|
31
|
-
export interface
|
|
31
|
+
export interface ContractMessage {
|
|
32
32
|
args: ContractMessageArg[];
|
|
33
33
|
default: boolean;
|
|
34
34
|
docs: string[];
|
|
@@ -37,15 +37,10 @@ export interface ContractConstructorMessage {
|
|
|
37
37
|
returnType: ContractTypeInfo;
|
|
38
38
|
selector: string;
|
|
39
39
|
}
|
|
40
|
-
export interface ContractMessage {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
docs: string[];
|
|
44
|
-
label: string;
|
|
40
|
+
export interface ContractConstructorMessage extends ContractMessage {
|
|
41
|
+
}
|
|
42
|
+
export interface ContractCallMessage extends ContractMessage {
|
|
45
43
|
mutates: boolean;
|
|
46
|
-
payable: boolean;
|
|
47
|
-
returnType: ContractTypeInfo;
|
|
48
|
-
selector: string;
|
|
49
44
|
}
|
|
50
45
|
export interface ContractType {
|
|
51
46
|
id: number;
|
package/types/v4.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContractConstructorMessage, ContractInformation,
|
|
1
|
+
import { ContractConstructorMessage, ContractInformation, ContractCallMessage, ContractSource, ContractStorage, ContractType, ContractTypeInfo } from './shared.js';
|
|
2
2
|
export interface ContractMetadataV4 {
|
|
3
3
|
source: ContractSource;
|
|
4
4
|
contract: ContractInformation;
|
|
@@ -12,8 +12,8 @@ export interface ContractSpecV4 {
|
|
|
12
12
|
docs: string[];
|
|
13
13
|
environment: ContractEnvironmentV4;
|
|
14
14
|
events: ContractEventV4[];
|
|
15
|
-
|
|
16
|
-
messages:
|
|
15
|
+
lang_error: ContractTypeInfo;
|
|
16
|
+
messages: ContractCallMessage[];
|
|
17
17
|
}
|
|
18
18
|
export interface ContractEventV4 {
|
|
19
19
|
args: unknown[];
|
package/utils.js
CHANGED
|
@@ -3,17 +3,17 @@ export const extractContractTypes = (contractMetadata) => {
|
|
|
3
3
|
const { types } = contractMetadata;
|
|
4
4
|
return types.map(({ type, id }) => ({
|
|
5
5
|
id,
|
|
6
|
-
|
|
6
|
+
typeDef: normalizeContractTypeDef(type.def),
|
|
7
7
|
params: [],
|
|
8
8
|
path: type?.path || [],
|
|
9
9
|
docs: [],
|
|
10
10
|
}));
|
|
11
11
|
};
|
|
12
12
|
export const normalizeContractTypeDef = (def) => {
|
|
13
|
-
let
|
|
13
|
+
let type;
|
|
14
14
|
let value;
|
|
15
15
|
if (def.variant) {
|
|
16
|
-
|
|
16
|
+
type = 'Enum';
|
|
17
17
|
value = {
|
|
18
18
|
members: def.variant.variants?.map((variant) => ({
|
|
19
19
|
fields: variant.fields?.map((fields) => ({ typeId: fields.type, typeName: fields.typeName })) || [],
|
|
@@ -23,19 +23,19 @@ export const normalizeContractTypeDef = (def) => {
|
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
else if (def.tuple) {
|
|
26
|
-
|
|
26
|
+
type = 'Tuple';
|
|
27
27
|
value = {
|
|
28
28
|
fields: def.tuple,
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
else if (def.sequence) {
|
|
32
|
-
|
|
32
|
+
type = 'Sequence';
|
|
33
33
|
value = {
|
|
34
34
|
typeParam: def.sequence.type,
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
else if (def.composite) {
|
|
38
|
-
|
|
38
|
+
type = 'Struct';
|
|
39
39
|
value = {
|
|
40
40
|
fields: def.composite.fields.map((one) => ({
|
|
41
41
|
typeId: one.type,
|
|
@@ -45,13 +45,13 @@ export const normalizeContractTypeDef = (def) => {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
else if (def.primitive) {
|
|
48
|
-
|
|
48
|
+
type = 'Primitive';
|
|
49
49
|
value = {
|
|
50
50
|
kind: def.primitive,
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
else if (def.array) {
|
|
54
|
-
|
|
54
|
+
type = 'SizedVec';
|
|
55
55
|
value = {
|
|
56
56
|
len: def.array.len,
|
|
57
57
|
typeParam: def.array.type,
|
|
@@ -60,7 +60,7 @@ export const normalizeContractTypeDef = (def) => {
|
|
|
60
60
|
else {
|
|
61
61
|
throw Error(`Invalid contract type def: ${JSON.stringify(def)}`);
|
|
62
62
|
}
|
|
63
|
-
return {
|
|
63
|
+
return { type, value };
|
|
64
64
|
};
|
|
65
65
|
const UNSUPPORTED_VERSIONS = ['V3', 'V2', 'V1'];
|
|
66
66
|
const SUPPORTED_VERSIONS = ['5', '4'];
|