@dedot/contracts 0.12.1-next.f19f185a.2 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/Contract.d.ts +4 -4
  2. package/Contract.js +41 -6
  3. package/ContractDeployer.d.ts +2 -2
  4. package/ContractDeployer.js +8 -6
  5. package/TypinkRegistry.d.ts +29 -6
  6. package/TypinkRegistry.js +144 -24
  7. package/cjs/Contract.js +44 -9
  8. package/cjs/ContractDeployer.js +10 -8
  9. package/cjs/TypinkRegistry.js +144 -24
  10. package/cjs/errors.js +3 -3
  11. package/cjs/executor/ConstructorQueryExecutor.js +49 -9
  12. package/cjs/executor/ConstructorTxExecutor.js +17 -6
  13. package/cjs/executor/QueryExecutor.js +30 -5
  14. package/cjs/executor/TxExecutor.js +10 -1
  15. package/cjs/executor/abstract/ContractExecutor.js +4 -5
  16. package/cjs/executor/abstract/DeployerExecutor.js +2 -2
  17. package/cjs/index.js +1 -1
  18. package/cjs/storage/BaseLazyObject.js +25 -0
  19. package/cjs/storage/LazyMapping.js +22 -0
  20. package/cjs/storage/LazyObject.js +18 -0
  21. package/cjs/storage/LazyStorageVec.js +54 -0
  22. package/cjs/storage/index.js +19 -0
  23. package/cjs/types/index.js +3 -0
  24. package/cjs/types/v6.js +2 -0
  25. package/cjs/utils/address.js +67 -0
  26. package/cjs/utils/ensure.js +68 -0
  27. package/cjs/utils/index.js +21 -0
  28. package/cjs/utils/proxy.js +11 -0
  29. package/cjs/utils/storage.js +44 -0
  30. package/cjs/{utils.js → utils/types.js} +31 -34
  31. package/errors.js +2 -2
  32. package/executor/ConstructorQueryExecutor.js +47 -7
  33. package/executor/ConstructorTxExecutor.js +18 -7
  34. package/executor/QueryExecutor.js +27 -2
  35. package/executor/TxExecutor.js +11 -2
  36. package/executor/abstract/ContractExecutor.d.ts +3 -4
  37. package/executor/abstract/ContractExecutor.js +2 -3
  38. package/executor/abstract/DeployerExecutor.js +1 -1
  39. package/index.d.ts +1 -1
  40. package/index.js +1 -1
  41. package/package.json +7 -6
  42. package/storage/BaseLazyObject.d.ts +10 -0
  43. package/storage/BaseLazyObject.js +21 -0
  44. package/storage/LazyMapping.d.ts +4 -0
  45. package/storage/LazyMapping.js +18 -0
  46. package/storage/LazyObject.d.ts +4 -0
  47. package/storage/LazyObject.js +14 -0
  48. package/storage/LazyStorageVec.d.ts +5 -0
  49. package/storage/LazyStorageVec.js +27 -0
  50. package/storage/index.d.ts +3 -0
  51. package/storage/index.js +3 -0
  52. package/types/index.d.ts +73 -11
  53. package/types/index.js +3 -0
  54. package/types/shared.d.ts +6 -18
  55. package/types/v4.d.ts +47 -3
  56. package/types/v5.d.ts +43 -4
  57. package/types/v6.d.ts +13 -0
  58. package/types/v6.js +1 -0
  59. package/utils/address.d.ts +30 -0
  60. package/utils/address.js +61 -0
  61. package/utils/ensure.d.ts +12 -0
  62. package/utils/ensure.js +59 -0
  63. package/utils/index.d.ts +5 -0
  64. package/utils/index.js +5 -0
  65. package/utils/proxy.d.ts +3 -0
  66. package/utils/proxy.js +7 -0
  67. package/utils/storage.d.ts +2 -0
  68. package/utils/storage.js +40 -0
  69. package/utils/types.d.ts +17 -0
  70. package/{utils.js → utils/types.js} +29 -30
  71. package/utils.d.ts +0 -13
@@ -0,0 +1,18 @@
1
+ import { concatU8a, toU8a } from '@dedot/utils';
2
+ import { BaseLazyObject } from './BaseLazyObject.js';
3
+ export class LazyMapping extends BaseLazyObject {
4
+ async get(key) {
5
+ const { id, type: { params }, } = this.typeDef;
6
+ const [keyType, valueType] = params;
7
+ const $Key = this.registry.findCodec(keyType.type);
8
+ const $Value = this.registry.findCodec(valueType.type);
9
+ const rootKey = this.findStorageRootLayout(id);
10
+ const encodedKey = $Key.tryEncode(key);
11
+ const storageKey = concatU8a(toU8a(rootKey), encodedKey);
12
+ const rawValue = await this.getContractStorage(storageKey);
13
+ if (rawValue) {
14
+ return $Value.tryDecode(rawValue);
15
+ }
16
+ return undefined;
17
+ }
18
+ }
@@ -0,0 +1,4 @@
1
+ import { BaseLazyObject } from './BaseLazyObject.js';
2
+ export declare class LazyObject extends BaseLazyObject {
3
+ get(): Promise<unknown>;
4
+ }
@@ -0,0 +1,14 @@
1
+ import { BaseLazyObject } from './BaseLazyObject.js';
2
+ export class LazyObject extends BaseLazyObject {
3
+ async get() {
4
+ const { id, type: { params }, } = this.typeDef;
5
+ const [valueType] = params;
6
+ const $Value = this.registry.findCodec(valueType.type);
7
+ const rootKey = this.findStorageRootLayout(id);
8
+ const rawValue = await this.getContractStorage(rootKey);
9
+ if (rawValue) {
10
+ return $Value.tryDecode(rawValue);
11
+ }
12
+ return undefined;
13
+ }
14
+ }
@@ -0,0 +1,5 @@
1
+ import { BaseLazyObject } from './BaseLazyObject.js';
2
+ export declare class LazyStorageVec extends BaseLazyObject {
3
+ len(): Promise<number>;
4
+ get(index: number): Promise<unknown>;
5
+ }
@@ -0,0 +1,27 @@
1
+ import * as $ from '@dedot/shape';
2
+ import { concatU8a, toU8a } from '@dedot/utils';
3
+ import { BaseLazyObject } from './BaseLazyObject.js';
4
+ export class LazyStorageVec extends BaseLazyObject {
5
+ async len() {
6
+ const { id } = this.typeDef;
7
+ const rootKey = this.findStorageRootLayout(id);
8
+ const rawValue = await this.getContractStorage(rootKey);
9
+ if (rawValue) {
10
+ return $.u32.tryDecode(rawValue);
11
+ }
12
+ return 0;
13
+ }
14
+ async get(index) {
15
+ const { id, type: { params }, } = this.typeDef;
16
+ const [valueType] = params;
17
+ const $Value = this.registry.findCodec(valueType.type);
18
+ const rootKey = this.findStorageRootLayout(id);
19
+ const encodedKey = $.u32.tryEncode(index);
20
+ const storageKey = concatU8a(toU8a(rootKey), encodedKey);
21
+ const rawValue = await this.getContractStorage(storageKey);
22
+ if (rawValue) {
23
+ return $Value.tryDecode(rawValue);
24
+ }
25
+ return undefined;
26
+ }
27
+ }
@@ -0,0 +1,3 @@
1
+ export * from './LazyObject.js';
2
+ export * from './LazyMapping.js';
3
+ export * from './LazyStorageVec.js';
@@ -0,0 +1,3 @@
1
+ export * from './LazyObject.js';
2
+ export * from './LazyMapping.js';
3
+ export * from './LazyStorageVec.js';
package/types/index.d.ts CHANGED
@@ -1,10 +1,14 @@
1
1
  import { SubstrateApi } from '@dedot/api/chaintypes';
2
- import { AccountId32, AccountId32Like, BytesLike, Weight } from '@dedot/codecs';
3
- import { AnyFunc, AsyncMethod, GenericSubstrateApi, IEventRecord, RpcVersion, Unsub, VersionedGenericSubstrateApi } from '@dedot/types';
4
- import { ContractCallMessage, ContractConstructorMessage } from './shared.js';
2
+ import { AccountId32Like, type Bytes, BytesLike, type DispatchError, Extrinsic, type H256, type Result, Weight } from '@dedot/codecs';
3
+ import { AnyFunc, AsyncMethod, GenericSubstrateApi, IEventRecord, ISubmittableExtrinsic, RpcVersion, Unsub, VersionedGenericSubstrateApi } from '@dedot/types';
4
+ import { ContractAddress, ContractCallMessage, ContractConstructorMessage } from './shared.js';
5
5
  import { ContractEventV4, ContractMetadataV4 } from './v4.js';
6
6
  import { ContractEventV5, ContractMetadataV5 } from './v5.js';
7
+ import { ContractMetadataV6 } from './v6.js';
7
8
  export * from './shared.js';
9
+ export * from './v4.js';
10
+ export * from './v5.js';
11
+ export * from './v6.js';
8
12
  export type ContractEventMeta = ContractEventV4 | ContractEventV5;
9
13
  /**
10
14
  * Flags used by a contract to customize exit behaviour.
@@ -18,17 +22,61 @@ export interface GenericContractCallResult<DecodedData = any, ContractResult = a
18
22
  data: DecodedData;
19
23
  raw: ContractResult;
20
24
  flags: ReturnFlags;
25
+ inputData: Bytes;
21
26
  }
22
27
  export interface GenericConstructorCallResult<DecodedData = any, ContractResult = any> extends GenericContractCallResult<DecodedData, ContractResult> {
23
- address: AccountId32;
28
+ address: ContractAddress;
29
+ }
30
+ export type ContractCode = {
31
+ type: 'Upload';
32
+ value: Bytes;
33
+ } | {
34
+ type: 'Existing';
35
+ value: H256;
36
+ };
37
+ export type WeightV2 = {
38
+ refTime: bigint;
39
+ proofSize: bigint;
40
+ };
41
+ export type StorageDeposit = {
42
+ type: 'Refund';
43
+ value: bigint;
44
+ } | {
45
+ type: 'Charge';
46
+ value: bigint;
47
+ };
48
+ export type ExecReturnValue = {
49
+ flags: {
50
+ bits: number;
51
+ };
52
+ data: Bytes;
53
+ };
54
+ export type InstantiateReturnValue = {
55
+ result: ExecReturnValue;
56
+ address: ContractAddress;
57
+ };
58
+ export type ContractCallResult<_ extends GenericSubstrateApi> = {
59
+ gasConsumed: WeightV2;
60
+ gasRequired: WeightV2;
61
+ storageDeposit: StorageDeposit;
62
+ debugMessage?: Bytes;
63
+ result: Result<ExecReturnValue, DispatchError>;
64
+ };
65
+ export type ContractInstantiateResult<_ extends GenericSubstrateApi> = {
66
+ gasConsumed: WeightV2;
67
+ gasRequired: WeightV2;
68
+ storageDeposit: StorageDeposit;
69
+ debugMessage?: Bytes;
70
+ result: Result<InstantiateReturnValue, DispatchError>;
71
+ };
72
+ type SubmittableExtrinsic = ISubmittableExtrinsic & Extrinsic;
73
+ export type ContractSubmittableExtrinsic<_ extends GenericSubstrateApi> = SubmittableExtrinsic;
74
+ export type GenericInstantiateSubmittableExtrinsic<_ extends GenericSubstrateApi> = SubmittableExtrinsic;
75
+ export type ContractMetadata = ContractMetadataV4 | ContractMetadataV5 | ContractMetadataV6;
76
+ export interface LooseContractMetadata {
77
+ version: number | string;
78
+ [prop: string]: any;
24
79
  }
25
- export type ContractCallResult<ChainApi extends GenericSubstrateApi> = Awaited<ReturnType<ChainApi['call']['contractsApi']['call']>>;
26
- export type ContractInstantiateResult<ChainApi extends GenericSubstrateApi> = Awaited<ReturnType<ChainApi['call']['contractsApi']['instantiate']>>;
27
- export type ContractSubmittableExtrinsic<ChainApi extends GenericSubstrateApi> = ReturnType<ChainApi['tx']['contracts']['call']>;
28
- export type InstantiateWithCodeSubmittableExtrinsic<ChainApi extends GenericSubstrateApi> = ReturnType<ChainApi['tx']['contracts']['instantiateWithCode']>;
29
- export type InstantiateSubmittableExtrinsic<ChainApi extends GenericSubstrateApi> = ReturnType<ChainApi['tx']['contracts']['instantiate']>;
30
- export type GenericInstantiateSubmittableExtrinsic<ChainApi extends GenericSubstrateApi> = InstantiateSubmittableExtrinsic<ChainApi> | InstantiateWithCodeSubmittableExtrinsic<ChainApi>;
31
- export type ContractMetadata = ContractMetadataV4 | ContractMetadataV5;
32
80
  export type CallOptions = {
33
81
  value?: bigint;
34
82
  gasLimit?: Weight | undefined;
@@ -89,13 +137,21 @@ export interface GenericContractEvents<_ extends GenericSubstrateApi> {
89
137
  [event: string]: GenericContractEvent;
90
138
  }
91
139
  export type GenericInkLangError = 'CouldNotReadInput' | any;
140
+ export type GenericRootStorage = any;
141
+ export type GenericLazyStorage = any;
92
142
  export interface GenericContractApi<Rv extends RpcVersion = RpcVersion, ChainApi extends VersionedGenericSubstrateApi = SubstrateApi> {
93
143
  query: GenericContractQuery<ChainApi[Rv]>;
94
144
  tx: GenericContractTx<ChainApi[Rv]>;
95
145
  constructorQuery: GenericConstructorQuery<ChainApi[Rv]>;
96
146
  constructorTx: GenericConstructorTx<ChainApi[Rv]>;
97
147
  events: GenericContractEvents<ChainApi[Rv]>;
148
+ storage: {
149
+ root(): Promise<GenericRootStorage>;
150
+ lazy(): GenericLazyStorage;
151
+ };
98
152
  types: {
153
+ RootStorage: GenericRootStorage;
154
+ LazyStorage: GenericLazyStorage;
99
155
  LangError: GenericInkLangError;
100
156
  ChainApi: ChainApi[Rv];
101
157
  };
@@ -103,3 +159,9 @@ export interface GenericContractApi<Rv extends RpcVersion = RpcVersion, ChainApi
103
159
  export interface ExecutionOptions {
104
160
  defaultCaller?: AccountId32Like;
105
161
  }
162
+ type HasGetter<T> = T extends {
163
+ get: (...args: any[]) => any;
164
+ } ? true : false;
165
+ export type WithLazyStorage<T> = {
166
+ [K in keyof T as HasGetter<T[K]> extends true ? K : T[K] extends object ? keyof WithLazyStorage<T[K]> extends never ? never : K : never]: T[K] extends object ? HasGetter<T[K]> extends true ? T[K] : WithLazyStorage<T[K]> : never;
167
+ };
package/types/index.js CHANGED
@@ -1 +1,4 @@
1
1
  export * from './shared.js';
2
+ export * from './v4.js';
3
+ export * from './v5.js';
4
+ export * from './v6.js';
package/types/shared.d.ts CHANGED
@@ -1,20 +1,19 @@
1
+ export type ContractAddress = string;
2
+ export interface ContractInformation {
3
+ name: string;
4
+ version: string;
5
+ authors: string[];
6
+ }
1
7
  export interface ContractSource {
2
8
  hash: string;
3
- wasm?: string;
4
9
  language: string;
5
10
  compiler: string;
6
11
  build_info: BuildInfo;
7
12
  }
8
- export interface ContractInformation {
9
- name: string;
10
- version: string;
11
- authors: string[];
12
- }
13
13
  export interface BuildInfo {
14
14
  build_mode: string;
15
15
  cargo_contract_version: string;
16
16
  rust_toolchain: string;
17
- wasm_opt_settings: WasmOptSettings;
18
17
  }
19
18
  export interface WasmOptSettings {
20
19
  keep_debug_symbols: boolean;
@@ -96,17 +95,6 @@ export interface ParamInfo {
96
95
  name: string;
97
96
  type: number;
98
97
  }
99
- export interface ContractStorage {
100
- root: {
101
- layout: {
102
- struct: {
103
- fields: any[];
104
- name: string;
105
- };
106
- };
107
- root_key: string;
108
- };
109
- }
110
98
  export interface ContractEventArg extends ContractMessageArg {
111
99
  docs: string[];
112
100
  indexed: boolean;
package/types/v4.d.ts CHANGED
@@ -1,12 +1,18 @@
1
- import { ContractConstructorMessage, ContractEventArg, ContractInformation, ContractCallMessage, ContractSource, ContractStorage, ContractType, ContractTypeInfo } from './shared.js';
1
+ import { BuildInfo, ContractCallMessage, ContractConstructorMessage, ContractEventArg, ContractInformation, ContractSource, ContractType, ContractTypeInfo, WasmOptSettings } from './shared.js';
2
2
  export interface ContractMetadataV4 {
3
- source: ContractSource;
3
+ source: ContractSourceV4;
4
4
  contract: ContractInformation;
5
5
  spec: ContractSpecV4;
6
- storage: ContractStorage;
6
+ storage: ContractStorageV4;
7
7
  types: ContractType[];
8
8
  version: '4';
9
9
  }
10
+ export interface ContractSourceV4 extends ContractSource {
11
+ wasm?: string;
12
+ build_info: BuildInfo & {
13
+ wasm_opt_settings: WasmOptSettings;
14
+ };
15
+ }
10
16
  export interface ContractSpecV4 {
11
17
  constructors: ContractConstructorMessage[];
12
18
  docs: string[];
@@ -29,3 +35,41 @@ export interface ContractEnvironmentV4 {
29
35
  maxEventTopics: number;
30
36
  timestamp: ContractTypeInfo;
31
37
  }
38
+ export interface StructLayoutV4 {
39
+ name: string;
40
+ fields: {
41
+ name: string;
42
+ layout: AnyLayoutV4;
43
+ }[];
44
+ }
45
+ export interface LeafLayoutV4 {
46
+ key: string;
47
+ ty: number;
48
+ }
49
+ export interface HashLayoutV4 {
50
+ }
51
+ export interface ArrayLayoutV4 {
52
+ offset: string;
53
+ len: number;
54
+ layout: AnyLayoutV4;
55
+ }
56
+ export interface EnumLayoutV4 {
57
+ name: string;
58
+ dispatch_key: string;
59
+ variants: Record<number, StructLayoutV4>;
60
+ }
61
+ export interface RootLayoutV4 {
62
+ root_key: string;
63
+ layout: AnyLayoutV4;
64
+ }
65
+ export type AnyLayoutV4 = {
66
+ struct?: StructLayoutV4;
67
+ leaf?: LeafLayoutV4;
68
+ hash?: HashLayoutV4;
69
+ array?: ArrayLayoutV4;
70
+ enum?: EnumLayoutV4;
71
+ root?: RootLayoutV4;
72
+ };
73
+ export interface ContractStorageV4 {
74
+ root: RootLayoutV4;
75
+ }
package/types/v5.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { ContractInformation, ContractSource, ContractStorage, ContractType } from './shared.js';
2
- import { ContractEnvironmentV4, ContractEventV4, ContractSpecV4 } from './v4.js';
1
+ import { ContractInformation, ContractType } from './shared.js';
2
+ import { ContractEnvironmentV4, ContractEventV4, ContractSourceV4, ContractSpecV4 } from './v4.js';
3
3
  export interface ContractMetadataV5 {
4
- source: ContractSource;
4
+ source: ContractSourceV4;
5
5
  contract: ContractInformation;
6
6
  spec: ContractSpecV5;
7
- storage: ContractStorage;
7
+ storage: ContractStorageV5;
8
8
  types: ContractType[];
9
9
  version: 5;
10
10
  }
@@ -19,3 +19,42 @@ export interface ContractEventV5 extends ContractEventV4 {
19
19
  export interface ContractEnvironmentV5 extends ContractEnvironmentV4 {
20
20
  staticBufferSize: number;
21
21
  }
22
+ export interface StructLayoutV5 {
23
+ name: string;
24
+ fields: {
25
+ name: string;
26
+ layout: AnyLayoutV5;
27
+ }[];
28
+ }
29
+ export interface LeafLayoutV5 {
30
+ key: string;
31
+ ty: number;
32
+ }
33
+ export interface HashLayoutV5 {
34
+ }
35
+ export interface ArrayLayoutV5 {
36
+ offset: string;
37
+ len: number;
38
+ layout: AnyLayoutV5;
39
+ }
40
+ export interface EnumLayoutV5 {
41
+ name: string;
42
+ dispatch_key: string;
43
+ variants: Record<number, StructLayoutV5>;
44
+ }
45
+ export interface RootLayoutV5 {
46
+ root_key: string;
47
+ layout: AnyLayoutV5;
48
+ ty: number;
49
+ }
50
+ export type AnyLayoutV5 = {
51
+ struct?: StructLayoutV5;
52
+ leaf?: LeafLayoutV5;
53
+ hash?: HashLayoutV5;
54
+ array?: ArrayLayoutV5;
55
+ enum?: EnumLayoutV5;
56
+ root?: RootLayoutV5;
57
+ };
58
+ export interface ContractStorageV5 {
59
+ root: RootLayoutV5;
60
+ }
package/types/v6.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { ContractInformation, ContractSource, ContractType } from './shared';
2
+ import { ContractSpecV5, ContractStorageV5 } from './v5.js';
3
+ export interface ContractSourceV6 extends ContractSource {
4
+ contract_binary?: string;
5
+ }
6
+ export interface ContractMetadataV6 {
7
+ source: ContractSourceV6;
8
+ contract: ContractInformation;
9
+ spec: ContractSpecV5;
10
+ storage: ContractStorageV5;
11
+ types: ContractType[];
12
+ version: 6;
13
+ }
package/types/v6.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ import { AccountId20Like, AccountId32Like, BytesLike } from '@dedot/codecs';
2
+ import { HexString } from '@dedot/utils';
3
+ /**
4
+ * Calculate new contract's address is based on the deployer's address and a nonce
5
+ *
6
+ * Ref: https://github.com/paritytech/polkadot-sdk/blob/5405e473854b139f1d0735550d90687eaf1a13f9/substrate/frame/revive/src/address.rs#L197-L204
7
+ *
8
+ * @param deployer
9
+ * @param nonce
10
+ */
11
+ export declare function CREATE1(deployer: AccountId20Like, nonce: number): HexString;
12
+ /**
13
+ * Calculate contract's address deterministically based on the salt, deployer's address, and the code & input data.
14
+ *
15
+ * Ref: https://github.com/paritytech/polkadot-sdk/blob/5405e473854b139f1d0735550d90687eaf1a13f9/substrate/frame/revive/src/address.rs#L206-L219
16
+ *
17
+ * @param deployer
18
+ * @param code
19
+ * @param inputData Input data for the constructor call
20
+ * @param salt Salt for the deployment
21
+ */
22
+ export declare function CREATE2(deployer: AccountId20Like, code: BytesLike, inputData: BytesLike, salt: BytesLike): HexString;
23
+ /**
24
+ * Convert a substrate address (H256) to an evm address (H160)
25
+ *
26
+ * Ref: https://github.com/paritytech/polkadot-sdk/blob/5405e473854b139f1d0735550d90687eaf1a13f9/substrate/frame/revive/src/address.rs#L101-L113
27
+ *
28
+ * @param accountId
29
+ */
30
+ export declare function toEvmAddress(accountId: AccountId32Like): HexString;
@@ -0,0 +1,61 @@
1
+ import { AccountId20, AccountId32 } from '@dedot/codecs';
2
+ import { concatU8a, hexToU8a, keccakAsU8a, toHex, toU8a, u8aToHex } from '@dedot/utils';
3
+ import { RLP } from '@ethereumjs/rlp';
4
+ /**
5
+ * Calculate new contract's address is based on the deployer's address and a nonce
6
+ *
7
+ * Ref: https://github.com/paritytech/polkadot-sdk/blob/5405e473854b139f1d0735550d90687eaf1a13f9/substrate/frame/revive/src/address.rs#L197-L204
8
+ *
9
+ * @param deployer
10
+ * @param nonce
11
+ */
12
+ export function CREATE1(deployer, nonce) {
13
+ const encodedData = RLP.encode([new AccountId20(deployer).raw, toHex(nonce)]);
14
+ const hash = keccakAsU8a(encodedData);
15
+ return u8aToHex(hash.subarray(12));
16
+ }
17
+ /**
18
+ * Calculate contract's address deterministically based on the salt, deployer's address, and the code & input data.
19
+ *
20
+ * Ref: https://github.com/paritytech/polkadot-sdk/blob/5405e473854b139f1d0735550d90687eaf1a13f9/substrate/frame/revive/src/address.rs#L206-L219
21
+ *
22
+ * @param deployer
23
+ * @param code
24
+ * @param inputData Input data for the constructor call
25
+ * @param salt Salt for the deployment
26
+ */
27
+ export function CREATE2(deployer, code, inputData, salt) {
28
+ const initCodeHash = keccakAsU8a(concatU8a(toU8a(code), toU8a(inputData)));
29
+ const bytes = new Uint8Array(1 + (20 + 32 + 32)); // 0xff + deployer + salt + initCodeHash
30
+ bytes[0] = 0xff;
31
+ bytes.set(hexToU8a(new AccountId20(deployer).raw), 1);
32
+ bytes.set(toU8a(salt), 21);
33
+ bytes.set(initCodeHash, 53);
34
+ return u8aToHex(keccakAsU8a(bytes).subarray(12));
35
+ }
36
+ function isEthDerived(accountId) {
37
+ if (accountId.length >= 32) {
38
+ return accountId.slice(20, accountId.length).every((byte) => byte === 0xee);
39
+ }
40
+ return false;
41
+ }
42
+ /**
43
+ * Convert a substrate address (H256) to an evm address (H160)
44
+ *
45
+ * Ref: https://github.com/paritytech/polkadot-sdk/blob/5405e473854b139f1d0735550d90687eaf1a13f9/substrate/frame/revive/src/address.rs#L101-L113
46
+ *
47
+ * @param accountId
48
+ */
49
+ export function toEvmAddress(accountId) {
50
+ const accountBytes = hexToU8a(new AccountId32(accountId).raw);
51
+ const accountBuffer = new Uint8Array(32);
52
+ accountBuffer.set(accountBytes.slice(0, 32));
53
+ if (isEthDerived(accountBytes)) {
54
+ // This was originally an eth address
55
+ // We just strip the 0xEE suffix to get the original address
56
+ return ('0x' + Buffer.from(accountBuffer.slice(0, 20)).toString('hex'));
57
+ }
58
+ else {
59
+ return u8aToHex(keccakAsU8a(accountBuffer).subarray(12));
60
+ }
61
+ }
@@ -0,0 +1,12 @@
1
+ import { ISubstrateClient } from '@dedot/api';
2
+ import { SubstrateApi } from '@dedot/api/chaintypes';
3
+ import { Hash } from '@dedot/codecs';
4
+ import { RpcVersion } from '@dedot/types';
5
+ import { TypinkRegistry } from 'src/TypinkRegistry';
6
+ import { ContractAddress, LooseContractMetadata } from 'src/types';
7
+ export declare const ensureStorageApiSupports: (version: string | number) => void;
8
+ export declare function ensurePalletPresence(client: ISubstrateClient<SubstrateApi[RpcVersion]>, registry: TypinkRegistry): void;
9
+ export declare function ensureContractPresence(client: ISubstrateClient<SubstrateApi[RpcVersion]>, registry: TypinkRegistry, address: ContractAddress): Promise<void>;
10
+ export declare function ensureValidContractAddress(address: ContractAddress, registry: TypinkRegistry): void;
11
+ export declare function ensureValidCodeHashOrCode(codeHashOrCode: Hash | Uint8Array | string, registry: TypinkRegistry): void;
12
+ export declare function ensureSupportedContractMetadataVersion(metadata: LooseContractMetadata): void;
@@ -0,0 +1,59 @@
1
+ import { accountId32ToHex } from '@dedot/codecs';
2
+ import { assert, DedotError, ensurePresence, hexToU8a, isEvmAddress, isPvm, isWasm, toU8a, } from '@dedot/utils';
3
+ export const ensureStorageApiSupports = (version) => {
4
+ const numberedVersion = typeof version === 'number' ? version : parseInt(version);
5
+ assert(numberedVersion >= 5, `Contract Storage Api Only Available for metadata version >= 5, current version: ${version}`);
6
+ };
7
+ export function ensurePalletPresence(client, registry) {
8
+ if (registry.isRevive()) {
9
+ try {
10
+ !!client.call.reviveApi.call.meta && !!client.tx.revive.call.meta;
11
+ }
12
+ catch {
13
+ throw new DedotError('Pallet Revive is not available');
14
+ }
15
+ }
16
+ else {
17
+ try {
18
+ !!client.call.contractsApi.call.meta && !!client.tx.contracts.call.meta;
19
+ }
20
+ catch {
21
+ throw new DedotError('Pallet Contracts is not available');
22
+ }
23
+ }
24
+ }
25
+ export async function ensureContractPresence(client, registry, address) {
26
+ const contractInfo = await (() => {
27
+ if (registry.isRevive()) {
28
+ return client.query.revive.contractInfoOf(address);
29
+ }
30
+ else {
31
+ return client.query.contracts.contractInfoOf(address);
32
+ }
33
+ })();
34
+ ensurePresence(contractInfo, `Contract with address ${address} does not exist on chain!`);
35
+ }
36
+ export function ensureValidContractAddress(address, registry) {
37
+ if (registry.isRevive()) {
38
+ assert(isEvmAddress(address), `Invalid contract address: ${address}. Expected an EVM 20-byte address as a hex string or a Uint8Array`);
39
+ }
40
+ else {
41
+ assert(hexToU8a(accountId32ToHex(address)).length === 32, `Invalid contract address: ${address}. Expected a Substrate 32-byte address as a hex string or a Uint8Array`);
42
+ }
43
+ }
44
+ export function ensureValidCodeHashOrCode(codeHashOrCode, registry) {
45
+ assert(toU8a(codeHashOrCode).length === 32 || (registry.isRevive() ? isPvm(codeHashOrCode) : isWasm(codeHashOrCode)), 'Invalid code hash or code: expected a hash of 32-byte or a valid PVM/WASM code as a hex string or a Uint8Array');
46
+ }
47
+ const UNSUPPORTED_VERSIONS = ['V3', 'V2', 'V1'];
48
+ const SUPPORTED_VERSIONS = [6, 5, '4'];
49
+ export function ensureSupportedContractMetadataVersion(metadata) {
50
+ // This is for V1, V2, V3
51
+ const unsupportedVersion = UNSUPPORTED_VERSIONS.find((o) => metadata[o]);
52
+ if (unsupportedVersion) {
53
+ throw new DedotError(`Unsupported metadata version: ${unsupportedVersion}`);
54
+ }
55
+ // This is for V4, V5, V6
56
+ if (!SUPPORTED_VERSIONS.includes(metadata.version)) {
57
+ throw new DedotError(`Unsupported metadata version: ${metadata.version}`);
58
+ }
59
+ }
@@ -0,0 +1,5 @@
1
+ export * from './types.js';
2
+ export * from './proxy.js';
3
+ export * from './ensure.js';
4
+ export * from './address.js';
5
+ export * from './storage.js';
package/utils/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './types.js';
2
+ export * from './proxy.js';
3
+ export * from './ensure.js';
4
+ export * from './address.js';
5
+ export * from './storage.js';
@@ -0,0 +1,3 @@
1
+ import { GenericSubstrateApi } from '@dedot/types';
2
+ import { Executor } from 'src/executor';
3
+ export declare function newProxyChain<ChainApi extends GenericSubstrateApi>(carrier: Executor<ChainApi>): unknown;
package/utils/proxy.js ADDED
@@ -0,0 +1,7 @@
1
+ export function newProxyChain(carrier) {
2
+ return new Proxy(carrier, {
3
+ get(target, property) {
4
+ return target.doExecute(property.toString());
5
+ },
6
+ });
7
+ }
@@ -0,0 +1,2 @@
1
+ import { AnyLayoutV5 } from '../types/index.js';
2
+ export declare function findStorageRootKey(layout: AnyLayoutV5, targetId: number): string | undefined;
@@ -0,0 +1,40 @@
1
+ export function findStorageRootKey(layout, targetId) {
2
+ if (layout.root) {
3
+ if (layout.root.ty === targetId) {
4
+ return layout.root.root_key;
5
+ }
6
+ else {
7
+ return findStorageRootKey(layout.root.layout, targetId);
8
+ }
9
+ }
10
+ else if (layout.array) {
11
+ return findStorageRootKey(layout.array.layout, targetId);
12
+ }
13
+ else if (layout.enum) {
14
+ for (const one of Object.values(layout.enum.variants)) {
15
+ for (const structField of one.fields) {
16
+ const potentialKey = findStorageRootKey(structField.layout, targetId);
17
+ if (potentialKey)
18
+ return potentialKey;
19
+ }
20
+ }
21
+ return undefined;
22
+ }
23
+ else if (layout.leaf) {
24
+ if (layout.leaf.ty === targetId) {
25
+ return layout.leaf.key;
26
+ }
27
+ else {
28
+ return undefined;
29
+ }
30
+ }
31
+ else if (layout.struct) {
32
+ for (const structField of layout.struct.fields) {
33
+ const potentialKey = findStorageRootKey(structField.layout, targetId);
34
+ if (potentialKey)
35
+ return potentialKey;
36
+ }
37
+ return undefined;
38
+ }
39
+ throw new Error(`Layout Not Supported: ${JSON.stringify(layout)}`);
40
+ }
@@ -0,0 +1,17 @@
1
+ import { PortableType, TypeDef } from '@dedot/codecs';
2
+ import { ContractMetadata, ContractTypeDef, ReturnFlags } from 'src/types';
3
+ export declare const extractContractTypes: (contractMetadata: ContractMetadata) => PortableType[];
4
+ export declare const normalizeContractTypeDef: (def: ContractTypeDef) => TypeDef;
5
+ export declare function normalizeLabel(label?: string): string;
6
+ export declare function toReturnFlags(bits: number): ReturnFlags;
7
+ export declare enum KnownLazyType {
8
+ LAZY = "LAZY",
9
+ MAPPING = "MAPPING",
10
+ STORAGE_VEC = "STORAGE_VEC"
11
+ }
12
+ /**
13
+ * Check if a type is lazy/non-packed storage
14
+ *
15
+ * @param typePath
16
+ */
17
+ export declare function isLazyType(typePath?: string | string[] | undefined): KnownLazyType | undefined;