@dedot/contracts 0.17.0 → 0.17.1-next.db98ff20.1

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 (113) hide show
  1. package/Contract.d.ts +5 -4
  2. package/Contract.js +42 -15
  3. package/ContractDeployer.d.ts +5 -4
  4. package/ContractDeployer.js +27 -10
  5. package/SolRegistry.d.ts +22 -0
  6. package/SolRegistry.js +64 -0
  7. package/TypinkRegistry.d.ts +2 -1
  8. package/TypinkRegistry.js +3 -1
  9. package/cjs/Contract.js +43 -16
  10. package/cjs/ContractDeployer.js +25 -8
  11. package/cjs/SolRegistry.js +68 -0
  12. package/cjs/TypinkRegistry.js +2 -0
  13. package/cjs/errors.js +75 -1
  14. package/cjs/executor/index.js +2 -5
  15. package/cjs/executor/{ConstructorQueryExecutor.js → ink/ConstructorQueryExecutor.js} +3 -2
  16. package/cjs/executor/{ConstructorTxExecutor.js → ink/ConstructorTxExecutor.js} +4 -3
  17. package/cjs/executor/{QueryExecutor.js → ink/QueryExecutor.js} +4 -3
  18. package/cjs/executor/{TxExecutor.js → ink/TxExecutor.js} +1 -1
  19. package/cjs/executor/{abstract → ink/abstract}/ContractExecutor.js +1 -1
  20. package/cjs/executor/{abstract → ink/abstract}/DeployerExecutor.js +1 -1
  21. package/cjs/executor/ink/index.js +22 -0
  22. package/cjs/executor/sol/SolConstructorQueryExecutor.js +81 -0
  23. package/cjs/executor/sol/SolConstructorTxExecutor.js +123 -0
  24. package/cjs/executor/sol/SolEventExecutor.js +57 -0
  25. package/cjs/executor/sol/SolQueryExecutor.js +83 -0
  26. package/cjs/executor/sol/SolTxExecutor.js +62 -0
  27. package/cjs/executor/sol/abstract/SolContractExecutor.js +12 -0
  28. package/cjs/executor/sol/abstract/SolDeployerExecutor.js +12 -0
  29. package/cjs/executor/sol/abstract/SolExecutor.js +17 -0
  30. package/cjs/executor/sol/abstract/index.js +19 -0
  31. package/cjs/executor/sol/index.js +22 -0
  32. package/cjs/types/index.js +2 -3
  33. package/cjs/types/ink/index.js +20 -0
  34. package/cjs/types/ink/v6.js +2 -0
  35. package/cjs/types/sol/abi.js +2 -0
  36. package/cjs/types/sol/index.js +17 -0
  37. package/cjs/utils/address.js +2 -2
  38. package/cjs/utils/ensure.js +40 -23
  39. package/cjs/utils/types.js +21 -1
  40. package/errors.d.ts +64 -5
  41. package/errors.js +70 -0
  42. package/executor/index.d.ts +2 -5
  43. package/executor/index.js +2 -5
  44. package/executor/{ConstructorQueryExecutor.d.ts → ink/ConstructorQueryExecutor.d.ts} +1 -2
  45. package/executor/{ConstructorQueryExecutor.js → ink/ConstructorQueryExecutor.js} +3 -2
  46. package/executor/{ConstructorTxExecutor.d.ts → ink/ConstructorTxExecutor.d.ts} +1 -2
  47. package/executor/{ConstructorTxExecutor.js → ink/ConstructorTxExecutor.js} +4 -3
  48. package/executor/{EventExecutor.d.ts → ink/EventExecutor.d.ts} +2 -2
  49. package/executor/{QueryExecutor.d.ts → ink/QueryExecutor.d.ts} +1 -2
  50. package/executor/{QueryExecutor.js → ink/QueryExecutor.js} +4 -3
  51. package/executor/{TxExecutor.d.ts → ink/TxExecutor.d.ts} +1 -2
  52. package/executor/{TxExecutor.js → ink/TxExecutor.js} +1 -1
  53. package/executor/{abstract → ink/abstract}/ContractExecutor.d.ts +2 -2
  54. package/executor/{abstract → ink/abstract}/ContractExecutor.js +1 -1
  55. package/executor/{abstract → ink/abstract}/DeployerExecutor.d.ts +2 -2
  56. package/executor/{abstract → ink/abstract}/DeployerExecutor.js +1 -1
  57. package/executor/{abstract → ink/abstract}/Executor.d.ts +2 -2
  58. package/executor/ink/index.d.ts +6 -0
  59. package/executor/ink/index.js +6 -0
  60. package/executor/sol/SolConstructorQueryExecutor.d.ts +5 -0
  61. package/executor/sol/SolConstructorQueryExecutor.js +77 -0
  62. package/executor/sol/SolConstructorTxExecutor.d.ts +5 -0
  63. package/executor/sol/SolConstructorTxExecutor.js +119 -0
  64. package/executor/sol/SolEventExecutor.d.ts +6 -0
  65. package/executor/sol/SolEventExecutor.js +53 -0
  66. package/executor/sol/SolQueryExecutor.d.ts +5 -0
  67. package/executor/sol/SolQueryExecutor.js +79 -0
  68. package/executor/sol/SolTxExecutor.d.ts +5 -0
  69. package/executor/sol/SolTxExecutor.js +58 -0
  70. package/executor/sol/abstract/SolContractExecutor.d.ts +9 -0
  71. package/executor/sol/abstract/SolContractExecutor.js +8 -0
  72. package/executor/sol/abstract/SolDeployerExecutor.d.ts +11 -0
  73. package/executor/sol/abstract/SolDeployerExecutor.js +8 -0
  74. package/executor/sol/abstract/SolExecutor.d.ts +13 -0
  75. package/executor/sol/abstract/SolExecutor.js +13 -0
  76. package/executor/sol/abstract/index.d.ts +3 -0
  77. package/executor/sol/abstract/index.js +3 -0
  78. package/executor/sol/index.d.ts +6 -0
  79. package/executor/sol/index.js +6 -0
  80. package/package.json +7 -7
  81. package/storage/BaseLazyObject.d.ts +1 -1
  82. package/types/index.d.ts +44 -121
  83. package/types/index.js +2 -3
  84. package/types/ink/index.d.ts +9 -0
  85. package/types/ink/index.js +4 -0
  86. package/types/ink/shared.d.ts +100 -0
  87. package/types/ink/v6.js +1 -0
  88. package/types/shared.d.ts +80 -99
  89. package/types/sol/abi.d.ts +45 -0
  90. package/types/sol/abi.js +1 -0
  91. package/types/sol/index.d.ts +1 -0
  92. package/types/sol/index.js +1 -0
  93. package/utils/address.js +2 -2
  94. package/utils/ensure.d.ts +8 -7
  95. package/utils/ensure.js +38 -22
  96. package/utils/types.d.ts +20 -2
  97. package/utils/types.js +18 -0
  98. /package/cjs/executor/{EventExecutor.js → ink/EventExecutor.js} +0 -0
  99. /package/cjs/executor/{abstract → ink/abstract}/Executor.js +0 -0
  100. /package/cjs/executor/{abstract → ink/abstract}/index.js +0 -0
  101. /package/cjs/types/{v4.js → ink/shared.js} +0 -0
  102. /package/cjs/types/{v5.js → ink/v4.js} +0 -0
  103. /package/cjs/types/{v6.js → ink/v5.js} +0 -0
  104. /package/executor/{EventExecutor.js → ink/EventExecutor.js} +0 -0
  105. /package/executor/{abstract → ink/abstract}/Executor.js +0 -0
  106. /package/executor/{abstract → ink/abstract}/index.d.ts +0 -0
  107. /package/executor/{abstract → ink/abstract}/index.js +0 -0
  108. /package/types/{v4.js → ink/shared.js} +0 -0
  109. /package/types/{v4.d.ts → ink/v4.d.ts} +0 -0
  110. /package/types/{v5.js → ink/v4.js} +0 -0
  111. /package/types/{v5.d.ts → ink/v5.d.ts} +0 -0
  112. /package/types/{v6.js → ink/v5.js} +0 -0
  113. /package/types/{v6.d.ts → ink/v6.d.ts} +0 -0
package/Contract.d.ts CHANGED
@@ -1,16 +1,17 @@
1
1
  import { ISubstrateClient } from '@dedot/api';
2
2
  import { IEventRecord } from '@dedot/types';
3
+ import { SolRegistry } from './SolRegistry.js';
3
4
  import { TypinkRegistry } from './TypinkRegistry.js';
4
- import { ContractAddress, ContractEvent, ContractMetadata, ExecutionOptions, GenericContractApi, LooseContractMetadata } from './types/index.js';
5
+ import { AB, ContractAddress, ContractEvent, ContractMetadata, ExecutionOptions, GenericContractApi, LooseContractMetadata, SolAbi } from './types/index.js';
5
6
  export declare class Contract<ContractApi extends GenericContractApi = GenericContractApi> {
6
7
  #private;
7
8
  readonly client: ISubstrateClient<ContractApi['types']['ChainApi']>;
8
- constructor(client: ISubstrateClient<ContractApi['types']['ChainApi']>, metadata: LooseContractMetadata | string, address: ContractAddress, options?: ExecutionOptions);
9
+ constructor(client: ISubstrateClient<ContractApi['types']['ChainApi']>, metadata: LooseContractMetadata | SolAbi | string, address: ContractAddress, options?: ExecutionOptions);
9
10
  decodeEvent(eventRecord: IEventRecord): ContractEvent;
10
11
  decodeEvents(eventRecords: IEventRecord[]): ContractEvent[];
11
- get metadata(): ContractMetadata;
12
12
  get address(): ContractAddress;
13
- get registry(): TypinkRegistry;
13
+ get metadata(): AB<ContractApi['metadataType'], ContractMetadata, SolAbi>;
14
+ get registry(): AB<ContractApi['metadataType'], TypinkRegistry, SolRegistry>;
14
15
  get query(): ContractApi['query'];
15
16
  get tx(): ContractApi['tx'];
16
17
  get events(): ContractApi['events'];
package/Contract.js CHANGED
@@ -1,21 +1,37 @@
1
1
  import { DedotError, toHex, toU8a } from '@dedot/utils';
2
+ import { SolRegistry } from './SolRegistry.js';
2
3
  import { TypinkRegistry } from './TypinkRegistry.js';
3
- import { EventExecutor, QueryExecutor, TxExecutor } from './executor/index.js';
4
- import { ensurePalletPresence, ensureStorageApiSupports, ensureSupportedContractMetadataVersion, ensureValidContractAddress, newProxyChain, } from './utils/index.js';
4
+ import { SolEventExecutor, SolQueryExecutor, SolTxExecutor } from './executor/index.js';
5
+ import { EventExecutor, QueryExecutor, TxExecutor } from './executor/ink/index.js';
6
+ import { ensurePalletPresence, ensureStorageApiSupports, ensureSupportedContractMetadataVersion, ensureValidContractAddress, isInkAbi, isSolAbi, newProxyChain, } from './utils/index.js';
5
7
  export class Contract {
6
8
  client;
7
9
  #registry;
8
- #address;
9
10
  #metadata;
11
+ #address;
12
+ #isInk = false;
10
13
  #options;
11
14
  constructor(client, metadata, address, options) {
12
15
  this.client = client;
13
- this.#metadata = (typeof metadata === 'string' ? JSON.parse(metadata) : metadata);
14
- ensureSupportedContractMetadataVersion(this.metadata);
15
- const getStorage = this.#getStorage.bind(this);
16
- this.#registry = new TypinkRegistry(this.metadata, { getStorage });
17
- ensurePalletPresence(client, this.registry);
18
- ensureValidContractAddress(address, this.registry);
16
+ this.#metadata = typeof metadata === 'string' ? JSON.parse(metadata) : metadata;
17
+ if (isInkAbi(this.metadata)) {
18
+ this.#isInk = true;
19
+ ensureSupportedContractMetadataVersion(this.metadata);
20
+ const getStorage = this.#getStorage.bind(this);
21
+ // @ts-ignore
22
+ this.#registry = new TypinkRegistry(this.metadata, { getStorage });
23
+ ensurePalletPresence(client, this.registry.isRevive());
24
+ ensureValidContractAddress(address, this.registry.isRevive());
25
+ }
26
+ else if (isSolAbi(this.metadata)) {
27
+ // @ts-ignore
28
+ this.#registry = new SolRegistry(this.metadata);
29
+ ensurePalletPresence(client, true);
30
+ ensureValidContractAddress(address, true);
31
+ }
32
+ else {
33
+ throw new DedotError('Unknown metadata format (neither ink! nor Solidity ABI)');
34
+ }
19
35
  this.#address = address;
20
36
  this.#options = options;
21
37
  }
@@ -25,39 +41,50 @@ export class Contract {
25
41
  decodeEvents(eventRecords) {
26
42
  return this.#registry.decodeEvents(eventRecords, this.address);
27
43
  }
28
- get metadata() {
29
- return this.#metadata;
30
- }
31
44
  get address() {
32
45
  return this.#address;
33
46
  }
47
+ get metadata() {
48
+ return this.#metadata;
49
+ }
34
50
  get registry() {
35
51
  return this.#registry;
36
52
  }
37
53
  get query() {
38
- return newProxyChain(new QueryExecutor(this.client, this.#registry, this.#address, this.#options));
54
+ const Executor = this.#isInk ? QueryExecutor : SolQueryExecutor;
55
+ // @ts-ignore
56
+ return newProxyChain(new Executor(this.client, this.registry, this.address, this.options));
39
57
  }
40
58
  get tx() {
41
- return newProxyChain(new TxExecutor(this.client, this.#registry, this.#address, this.#options));
59
+ const Executor = this.#isInk ? TxExecutor : SolTxExecutor;
60
+ // @ts-ignore
61
+ return newProxyChain(new Executor(this.client, this.registry, this.address, this.options));
42
62
  }
43
63
  get events() {
44
- return newProxyChain(new EventExecutor(this.client, this.#registry, this.#address, this.#options));
64
+ const Executor = this.#isInk ? EventExecutor : SolEventExecutor;
65
+ // @ts-ignore
66
+ return newProxyChain(new Executor(this.client, this.registry, this.address, this.options));
45
67
  }
46
68
  get options() {
47
69
  return this.#options;
48
70
  }
49
71
  get storage() {
72
+ if (!this.#isInk) {
73
+ throw new DedotError('Storage API is only available for ink! contracts');
74
+ }
50
75
  return {
51
76
  root: async () => {
52
77
  ensureStorageApiSupports(this.metadata.version);
53
78
  const { ty, root_key } = this.metadata.storage.root;
54
79
  const rawValue = await this.#getStorage(root_key);
80
+ // @ts-ignore
55
81
  return this.registry.findCodec(ty).tryDecode(rawValue);
56
82
  },
57
83
  lazy: () => {
58
84
  ensureStorageApiSupports(this.metadata.version);
59
85
  const { ty } = this.metadata.storage.root;
60
86
  const $lazyCodec = this.registry.createLazyCodec(ty);
87
+ // @ts-ignore
61
88
  return $lazyCodec ? $lazyCodec.tryDecode('0x') : {};
62
89
  },
63
90
  };
@@ -1,13 +1,14 @@
1
1
  import { ISubstrateClient } from '@dedot/api';
2
2
  import { Hash } from '@dedot/codecs';
3
+ import { SolRegistry } from './SolRegistry.js';
3
4
  import { TypinkRegistry } from './TypinkRegistry.js';
4
- import { ContractMetadata, ExecutionOptions, GenericContractApi, LooseContractMetadata } from './types/index.js';
5
+ import { AB, ContractMetadata, ExecutionOptions, GenericContractApi, LooseContractMetadata, SolAbi } from './types/index.js';
5
6
  export declare class ContractDeployer<ContractApi extends GenericContractApi = GenericContractApi> {
6
7
  #private;
7
8
  readonly client: ISubstrateClient<ContractApi['types']['ChainApi']>;
8
- constructor(client: ISubstrateClient<ContractApi['types']['ChainApi']>, metadata: LooseContractMetadata | string, codeHashOrCode: Hash | Uint8Array | string, options?: ExecutionOptions);
9
- get metadata(): ContractMetadata;
10
- get registry(): TypinkRegistry;
9
+ constructor(client: ISubstrateClient<ContractApi['types']['ChainApi']>, metadata: AB<ContractApi['metadataType'], LooseContractMetadata, SolAbi> | string, codeHashOrCode: Hash | Uint8Array | string, options?: ExecutionOptions);
10
+ get metadata(): AB<ContractApi['metadataType'], ContractMetadata, SolAbi>;
11
+ get registry(): AB<ContractApi['metadataType'], TypinkRegistry, SolRegistry>;
11
12
  get tx(): ContractApi['constructorTx'];
12
13
  get query(): ContractApi['constructorQuery'];
13
14
  get options(): ExecutionOptions | undefined;
@@ -1,20 +1,31 @@
1
+ import { SolRegistry } from './SolRegistry.js';
1
2
  import { TypinkRegistry } from './TypinkRegistry.js';
2
- import { ConstructorQueryExecutor } from './executor/ConstructorQueryExecutor.js';
3
- import { ConstructorTxExecutor } from './executor/index.js';
4
- import { ensurePalletPresence, ensureSupportedContractMetadataVersion, ensureValidCodeHashOrCode, newProxyChain, } from './utils/index.js';
3
+ import { ConstructorQueryExecutor, ConstructorTxExecutor, SolConstructorQueryExecutor, SolConstructorTxExecutor, } from './executor/index.js';
4
+ import { ensurePalletPresence, ensureSupportedContractMetadataVersion, ensureValidCodeHashOrCode, isInkAbi, newProxyChain, } from './utils/index.js';
5
5
  export class ContractDeployer {
6
6
  client;
7
+ #isInk = false;
7
8
  #metadata;
8
9
  #registry;
9
10
  #code;
10
11
  #options;
11
12
  constructor(client, metadata, codeHashOrCode, options) {
12
13
  this.client = client;
13
- this.#metadata = (typeof metadata === 'string' ? JSON.parse(metadata) : metadata);
14
- ensureSupportedContractMetadataVersion(this.metadata);
15
- this.#registry = new TypinkRegistry(this.metadata);
16
- ensurePalletPresence(client, this.registry);
17
- ensureValidCodeHashOrCode(codeHashOrCode, this.registry);
14
+ this.#metadata = typeof metadata === 'string' ? JSON.parse(metadata) : metadata;
15
+ if (isInkAbi(this.metadata)) {
16
+ this.#isInk = true;
17
+ ensureSupportedContractMetadataVersion(this.metadata);
18
+ // @ts-ignore
19
+ this.#registry = new TypinkRegistry(this.metadata);
20
+ ensurePalletPresence(client, this.registry.isRevive());
21
+ ensureValidCodeHashOrCode(codeHashOrCode, this.registry.isRevive());
22
+ }
23
+ else {
24
+ // @ts-ignore
25
+ this.#registry = new SolRegistry(this.metadata);
26
+ ensurePalletPresence(client, true);
27
+ ensureValidCodeHashOrCode(codeHashOrCode, true);
28
+ }
18
29
  this.#code = codeHashOrCode;
19
30
  this.#options = options;
20
31
  }
@@ -25,10 +36,16 @@ export class ContractDeployer {
25
36
  return this.#registry;
26
37
  }
27
38
  get tx() {
28
- return newProxyChain(new ConstructorTxExecutor(this.client, this.#registry, this.#code, this.#options));
39
+ const Executor = this.#isInk ? ConstructorTxExecutor : SolConstructorTxExecutor;
40
+ return newProxyChain(
41
+ // @ts-ignore
42
+ new Executor(this.client, this.registry, this.#code, this.options));
29
43
  }
30
44
  get query() {
31
- return newProxyChain(new ConstructorQueryExecutor(this.client, this.#registry, this.#code, this.#options));
45
+ const Executor = this.#isInk ? ConstructorQueryExecutor : SolConstructorQueryExecutor;
46
+ return newProxyChain(
47
+ // @ts-ignore
48
+ new Executor(this.client, this.registry, this.#code, this.options));
32
49
  }
33
50
  get options() {
34
51
  return this.#options;
@@ -0,0 +1,22 @@
1
+ import { IEventRecord } from '@dedot/codecs/types';
2
+ import { LRUCache } from '@dedot/utils';
3
+ import { ContractAddress, SolAbi, ContractEvent, SolAbiFunction, SolAbiConstructor, SolAbiEvent, SolAbiError } from './types/index.js';
4
+ export declare class SolRegistry {
5
+ #private;
6
+ readonly abi: SolAbi;
7
+ readonly cache: LRUCache;
8
+ constructor(abi: SolAbi);
9
+ findAbiFunction(name: string): SolAbiFunction | undefined;
10
+ findTxAbiFunction(name: string): SolAbiFunction | undefined;
11
+ findAbiConstructor(): SolAbiConstructor;
12
+ findAbiEvent(name: string): SolAbiEvent | undefined;
13
+ findAbiError(name: string): SolAbiError | undefined;
14
+ decodeEvents(records: IEventRecord[], contract: ContractAddress): ContractEvent[];
15
+ decodeEvent(eventRecord: IEventRecord, contract: ContractAddress): {
16
+ name: string;
17
+ data: {};
18
+ } | {
19
+ name: string;
20
+ data?: undefined;
21
+ };
22
+ }
package/SolRegistry.js ADDED
@@ -0,0 +1,64 @@
1
+ import { assert, stringCamelCase, LRUCache } from '@dedot/utils';
2
+ import { decodeEventLog } from 'viem/utils';
3
+ export class SolRegistry {
4
+ abi;
5
+ cache;
6
+ constructor(abi) {
7
+ this.abi = abi;
8
+ this.cache = new LRUCache(500);
9
+ }
10
+ findAbiFunction(name) {
11
+ return this.abi.find((one) => one.type === 'function' && stringCamelCase(one.name) === name);
12
+ }
13
+ findTxAbiFunction(name) {
14
+ const found = this.findAbiFunction(name);
15
+ if (found && (found.stateMutability === 'payable' || found.stateMutability === 'nonpayable')) {
16
+ return found;
17
+ }
18
+ return undefined;
19
+ }
20
+ findAbiConstructor() {
21
+ let item = this.abi.find((a) => a.type === 'constructor');
22
+ return (item ||
23
+ {
24
+ inputs: [],
25
+ stateMutability: 'nonpayable',
26
+ type: 'constructor',
27
+ } // Fallback to default constructor
28
+ );
29
+ }
30
+ findAbiEvent(name) {
31
+ return this.abi.find((one) => one.type === 'event' && one.name === name);
32
+ }
33
+ findAbiError(name) {
34
+ return this.abi.find((one) => one.type === 'error' && one.name === name);
35
+ }
36
+ decodeEvents(records, contract) {
37
+ return records
38
+ .filter((eventRecord) => this.#isContractEmittedEvent(eventRecord.event, contract))
39
+ .map((eventRecord) => this.decodeEvent(eventRecord, contract));
40
+ }
41
+ decodeEvent(eventRecord, contract) {
42
+ assert(this.#isContractEmittedEvent(eventRecord.event, contract), 'Invalid ContractEmitted Event');
43
+ const event = eventRecord.event;
44
+ const signatureTopic = event.palletEvent.data.topics[0];
45
+ const { eventName, args: data } = decodeEventLog({
46
+ abi: this.abi,
47
+ data: event.palletEvent.data.data,
48
+ topics: [signatureTopic, ...event.palletEvent.data.topics],
49
+ });
50
+ return data ? { name: eventName, data } : { name: eventName };
51
+ }
52
+ #isContractEmittedEvent(event, contractAddress) {
53
+ const eventMatched = typeof event.palletEvent === 'object' && // --
54
+ event.palletEvent.name === 'ContractEmitted';
55
+ if (!eventMatched)
56
+ return false;
57
+ if (contractAddress) {
58
+ // @ts-ignore
59
+ const emittedContract = event.palletEvent.data?.contract;
60
+ return emittedContract === contractAddress;
61
+ }
62
+ return true;
63
+ }
64
+ }
@@ -1,7 +1,7 @@
1
1
  import { TypeId, TypeRegistry } from '@dedot/codecs';
2
2
  import * as $ from '@dedot/shape';
3
3
  import { IEventRecord } from '@dedot/types';
4
- import { HexString } from '@dedot/utils';
4
+ import { HexString, LRUCache } from '@dedot/utils';
5
5
  import { ContractAddress, ContractEvent, ContractMetadata } from './types/index.js';
6
6
  export interface TypinkRegistryOptions {
7
7
  /**
@@ -15,6 +15,7 @@ export declare class TypinkRegistry extends TypeRegistry {
15
15
  #private;
16
16
  readonly metadata: ContractMetadata;
17
17
  readonly options?: TypinkRegistryOptions | undefined;
18
+ readonly cache: LRUCache;
18
19
  constructor(metadata: ContractMetadata, options?: TypinkRegistryOptions | undefined);
19
20
  findCodec<I = unknown, O = I>(typeId: TypeId): $.Shape<I, O>;
20
21
  /**
package/TypinkRegistry.js CHANGED
@@ -1,16 +1,18 @@
1
1
  import { AccountId32, TypeRegistry } from '@dedot/codecs';
2
2
  import * as $ from '@dedot/shape';
3
- import { assert, DedotError, hexToU8a, stringCamelCase, stringPascalCase } from '@dedot/utils';
3
+ import { assert, DedotError, hexToU8a, stringCamelCase, stringPascalCase, LRUCache } from '@dedot/utils';
4
4
  import { LazyMapping, LazyObject, LazyStorageVec } from './storage/index.js';
5
5
  import { ensureSupportedContractMetadataVersion, extractContractTypes, isLazyType, KnownLazyType, } from './utils/index.js';
6
6
  export class TypinkRegistry extends TypeRegistry {
7
7
  metadata;
8
8
  options;
9
+ cache;
9
10
  constructor(metadata, options) {
10
11
  ensureSupportedContractMetadataVersion(metadata);
11
12
  super(extractContractTypes(metadata));
12
13
  this.metadata = metadata;
13
14
  this.options = options;
15
+ this.cache = new LRUCache(500);
14
16
  }
15
17
  findCodec(typeId) {
16
18
  const types = this.metadata.types;
package/cjs/Contract.js CHANGED
@@ -2,23 +2,39 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Contract = void 0;
4
4
  const utils_1 = require("@dedot/utils");
5
+ const SolRegistry_js_1 = require("./SolRegistry.js");
5
6
  const TypinkRegistry_js_1 = require("./TypinkRegistry.js");
6
7
  const index_js_1 = require("./executor/index.js");
7
- const index_js_2 = require("./utils/index.js");
8
+ const index_js_2 = require("./executor/ink/index.js");
9
+ const index_js_3 = require("./utils/index.js");
8
10
  class Contract {
9
11
  client;
10
12
  #registry;
11
- #address;
12
13
  #metadata;
14
+ #address;
15
+ #isInk = false;
13
16
  #options;
14
17
  constructor(client, metadata, address, options) {
15
18
  this.client = client;
16
- this.#metadata = (typeof metadata === 'string' ? JSON.parse(metadata) : metadata);
17
- (0, index_js_2.ensureSupportedContractMetadataVersion)(this.metadata);
18
- const getStorage = this.#getStorage.bind(this);
19
- this.#registry = new TypinkRegistry_js_1.TypinkRegistry(this.metadata, { getStorage });
20
- (0, index_js_2.ensurePalletPresence)(client, this.registry);
21
- (0, index_js_2.ensureValidContractAddress)(address, this.registry);
19
+ this.#metadata = typeof metadata === 'string' ? JSON.parse(metadata) : metadata;
20
+ if ((0, index_js_3.isInkAbi)(this.metadata)) {
21
+ this.#isInk = true;
22
+ (0, index_js_3.ensureSupportedContractMetadataVersion)(this.metadata);
23
+ const getStorage = this.#getStorage.bind(this);
24
+ // @ts-ignore
25
+ this.#registry = new TypinkRegistry_js_1.TypinkRegistry(this.metadata, { getStorage });
26
+ (0, index_js_3.ensurePalletPresence)(client, this.registry.isRevive());
27
+ (0, index_js_3.ensureValidContractAddress)(address, this.registry.isRevive());
28
+ }
29
+ else if ((0, index_js_3.isSolAbi)(this.metadata)) {
30
+ // @ts-ignore
31
+ this.#registry = new SolRegistry_js_1.SolRegistry(this.metadata);
32
+ (0, index_js_3.ensurePalletPresence)(client, true);
33
+ (0, index_js_3.ensureValidContractAddress)(address, true);
34
+ }
35
+ else {
36
+ throw new utils_1.DedotError('Unknown metadata format (neither ink! nor Solidity ABI)');
37
+ }
22
38
  this.#address = address;
23
39
  this.#options = options;
24
40
  }
@@ -28,39 +44,50 @@ class Contract {
28
44
  decodeEvents(eventRecords) {
29
45
  return this.#registry.decodeEvents(eventRecords, this.address);
30
46
  }
31
- get metadata() {
32
- return this.#metadata;
33
- }
34
47
  get address() {
35
48
  return this.#address;
36
49
  }
50
+ get metadata() {
51
+ return this.#metadata;
52
+ }
37
53
  get registry() {
38
54
  return this.#registry;
39
55
  }
40
56
  get query() {
41
- return (0, index_js_2.newProxyChain)(new index_js_1.QueryExecutor(this.client, this.#registry, this.#address, this.#options));
57
+ const Executor = this.#isInk ? index_js_2.QueryExecutor : index_js_1.SolQueryExecutor;
58
+ // @ts-ignore
59
+ return (0, index_js_3.newProxyChain)(new Executor(this.client, this.registry, this.address, this.options));
42
60
  }
43
61
  get tx() {
44
- return (0, index_js_2.newProxyChain)(new index_js_1.TxExecutor(this.client, this.#registry, this.#address, this.#options));
62
+ const Executor = this.#isInk ? index_js_2.TxExecutor : index_js_1.SolTxExecutor;
63
+ // @ts-ignore
64
+ return (0, index_js_3.newProxyChain)(new Executor(this.client, this.registry, this.address, this.options));
45
65
  }
46
66
  get events() {
47
- return (0, index_js_2.newProxyChain)(new index_js_1.EventExecutor(this.client, this.#registry, this.#address, this.#options));
67
+ const Executor = this.#isInk ? index_js_2.EventExecutor : index_js_1.SolEventExecutor;
68
+ // @ts-ignore
69
+ return (0, index_js_3.newProxyChain)(new Executor(this.client, this.registry, this.address, this.options));
48
70
  }
49
71
  get options() {
50
72
  return this.#options;
51
73
  }
52
74
  get storage() {
75
+ if (!this.#isInk) {
76
+ throw new utils_1.DedotError('Storage API is only available for ink! contracts');
77
+ }
53
78
  return {
54
79
  root: async () => {
55
- (0, index_js_2.ensureStorageApiSupports)(this.metadata.version);
80
+ (0, index_js_3.ensureStorageApiSupports)(this.metadata.version);
56
81
  const { ty, root_key } = this.metadata.storage.root;
57
82
  const rawValue = await this.#getStorage(root_key);
83
+ // @ts-ignore
58
84
  return this.registry.findCodec(ty).tryDecode(rawValue);
59
85
  },
60
86
  lazy: () => {
61
- (0, index_js_2.ensureStorageApiSupports)(this.metadata.version);
87
+ (0, index_js_3.ensureStorageApiSupports)(this.metadata.version);
62
88
  const { ty } = this.metadata.storage.root;
63
89
  const $lazyCodec = this.registry.createLazyCodec(ty);
90
+ // @ts-ignore
64
91
  return $lazyCodec ? $lazyCodec.tryDecode('0x') : {};
65
92
  },
66
93
  };
@@ -1,23 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ContractDeployer = void 0;
4
+ const SolRegistry_js_1 = require("./SolRegistry.js");
4
5
  const TypinkRegistry_js_1 = require("./TypinkRegistry.js");
5
- const ConstructorQueryExecutor_js_1 = require("./executor/ConstructorQueryExecutor.js");
6
6
  const index_js_1 = require("./executor/index.js");
7
7
  const index_js_2 = require("./utils/index.js");
8
8
  class ContractDeployer {
9
9
  client;
10
+ #isInk = false;
10
11
  #metadata;
11
12
  #registry;
12
13
  #code;
13
14
  #options;
14
15
  constructor(client, metadata, codeHashOrCode, options) {
15
16
  this.client = client;
16
- this.#metadata = (typeof metadata === 'string' ? JSON.parse(metadata) : metadata);
17
- (0, index_js_2.ensureSupportedContractMetadataVersion)(this.metadata);
18
- this.#registry = new TypinkRegistry_js_1.TypinkRegistry(this.metadata);
19
- (0, index_js_2.ensurePalletPresence)(client, this.registry);
20
- (0, index_js_2.ensureValidCodeHashOrCode)(codeHashOrCode, this.registry);
17
+ this.#metadata = typeof metadata === 'string' ? JSON.parse(metadata) : metadata;
18
+ if ((0, index_js_2.isInkAbi)(this.metadata)) {
19
+ this.#isInk = true;
20
+ (0, index_js_2.ensureSupportedContractMetadataVersion)(this.metadata);
21
+ // @ts-ignore
22
+ this.#registry = new TypinkRegistry_js_1.TypinkRegistry(this.metadata);
23
+ (0, index_js_2.ensurePalletPresence)(client, this.registry.isRevive());
24
+ (0, index_js_2.ensureValidCodeHashOrCode)(codeHashOrCode, this.registry.isRevive());
25
+ }
26
+ else {
27
+ // @ts-ignore
28
+ this.#registry = new SolRegistry_js_1.SolRegistry(this.metadata);
29
+ (0, index_js_2.ensurePalletPresence)(client, true);
30
+ (0, index_js_2.ensureValidCodeHashOrCode)(codeHashOrCode, true);
31
+ }
21
32
  this.#code = codeHashOrCode;
22
33
  this.#options = options;
23
34
  }
@@ -28,10 +39,16 @@ class ContractDeployer {
28
39
  return this.#registry;
29
40
  }
30
41
  get tx() {
31
- return (0, index_js_2.newProxyChain)(new index_js_1.ConstructorTxExecutor(this.client, this.#registry, this.#code, this.#options));
42
+ const Executor = this.#isInk ? index_js_1.ConstructorTxExecutor : index_js_1.SolConstructorTxExecutor;
43
+ return (0, index_js_2.newProxyChain)(
44
+ // @ts-ignore
45
+ new Executor(this.client, this.registry, this.#code, this.options));
32
46
  }
33
47
  get query() {
34
- return (0, index_js_2.newProxyChain)(new ConstructorQueryExecutor_js_1.ConstructorQueryExecutor(this.client, this.#registry, this.#code, this.#options));
48
+ const Executor = this.#isInk ? index_js_1.ConstructorQueryExecutor : index_js_1.SolConstructorQueryExecutor;
49
+ return (0, index_js_2.newProxyChain)(
50
+ // @ts-ignore
51
+ new Executor(this.client, this.registry, this.#code, this.options));
35
52
  }
36
53
  get options() {
37
54
  return this.#options;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SolRegistry = void 0;
4
+ const utils_1 = require("@dedot/utils");
5
+ const utils_2 = require("viem/utils");
6
+ class SolRegistry {
7
+ abi;
8
+ cache;
9
+ constructor(abi) {
10
+ this.abi = abi;
11
+ this.cache = new utils_1.LRUCache(500);
12
+ }
13
+ findAbiFunction(name) {
14
+ return this.abi.find((one) => one.type === 'function' && (0, utils_1.stringCamelCase)(one.name) === name);
15
+ }
16
+ findTxAbiFunction(name) {
17
+ const found = this.findAbiFunction(name);
18
+ if (found && (found.stateMutability === 'payable' || found.stateMutability === 'nonpayable')) {
19
+ return found;
20
+ }
21
+ return undefined;
22
+ }
23
+ findAbiConstructor() {
24
+ let item = this.abi.find((a) => a.type === 'constructor');
25
+ return (item ||
26
+ {
27
+ inputs: [],
28
+ stateMutability: 'nonpayable',
29
+ type: 'constructor',
30
+ } // Fallback to default constructor
31
+ );
32
+ }
33
+ findAbiEvent(name) {
34
+ return this.abi.find((one) => one.type === 'event' && one.name === name);
35
+ }
36
+ findAbiError(name) {
37
+ return this.abi.find((one) => one.type === 'error' && one.name === name);
38
+ }
39
+ decodeEvents(records, contract) {
40
+ return records
41
+ .filter((eventRecord) => this.#isContractEmittedEvent(eventRecord.event, contract))
42
+ .map((eventRecord) => this.decodeEvent(eventRecord, contract));
43
+ }
44
+ decodeEvent(eventRecord, contract) {
45
+ (0, utils_1.assert)(this.#isContractEmittedEvent(eventRecord.event, contract), 'Invalid ContractEmitted Event');
46
+ const event = eventRecord.event;
47
+ const signatureTopic = event.palletEvent.data.topics[0];
48
+ const { eventName, args: data } = (0, utils_2.decodeEventLog)({
49
+ abi: this.abi,
50
+ data: event.palletEvent.data.data,
51
+ topics: [signatureTopic, ...event.palletEvent.data.topics],
52
+ });
53
+ return data ? { name: eventName, data } : { name: eventName };
54
+ }
55
+ #isContractEmittedEvent(event, contractAddress) {
56
+ const eventMatched = typeof event.palletEvent === 'object' && // --
57
+ event.palletEvent.name === 'ContractEmitted';
58
+ if (!eventMatched)
59
+ return false;
60
+ if (contractAddress) {
61
+ // @ts-ignore
62
+ const emittedContract = event.palletEvent.data?.contract;
63
+ return emittedContract === contractAddress;
64
+ }
65
+ return true;
66
+ }
67
+ }
68
+ exports.SolRegistry = SolRegistry;
@@ -32,11 +32,13 @@ const index_js_2 = require("./utils/index.js");
32
32
  class TypinkRegistry extends codecs_1.TypeRegistry {
33
33
  metadata;
34
34
  options;
35
+ cache;
35
36
  constructor(metadata, options) {
36
37
  (0, index_js_2.ensureSupportedContractMetadataVersion)(metadata);
37
38
  super((0, index_js_2.extractContractTypes)(metadata));
38
39
  this.metadata = metadata;
39
40
  this.options = options;
41
+ this.cache = new utils_1.LRUCache(500);
40
42
  }
41
43
  findCodec(typeId) {
42
44
  const types = this.metadata.types;