@cosmwasm/ts-codegen 0.30.1 → 0.31.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. package/README.md +36 -30
  2. package/main/builder/builder.js +41 -4
  3. package/main/generators/create-helpers.js +38 -0
  4. package/main/helpers/contractContextBase.js +8 -0
  5. package/main/helpers/contractsContextTSX.js +8 -0
  6. package/main/helpers/index.js +31 -0
  7. package/main/plugins/client.js +11 -6
  8. package/main/plugins/message-composer.js +10 -6
  9. package/main/plugins/msg-builder.js +1 -1
  10. package/main/plugins/plugin-base.js +9 -2
  11. package/main/plugins/provider-bundle.js +146 -0
  12. package/main/plugins/provider.js +170 -0
  13. package/main/plugins/react-query.js +1 -1
  14. package/main/plugins/recoil.js +1 -1
  15. package/main/plugins/types.js +1 -1
  16. package/main/utils/files.js +77 -0
  17. package/main/utils/unused.js +68 -0
  18. package/module/builder/builder.js +28 -2
  19. package/module/generators/create-helpers.js +25 -0
  20. package/module/helpers/contractContextBase.js +92 -0
  21. package/module/helpers/contractsContextTSX.js +73 -0
  22. package/module/helpers/index.js +2 -0
  23. package/module/plugins/client.js +13 -10
  24. package/module/plugins/message-composer.js +12 -10
  25. package/module/plugins/msg-builder.js +1 -1
  26. package/module/plugins/plugin-base.js +15 -8
  27. package/module/plugins/provider-bundle.js +65 -0
  28. package/module/plugins/provider.js +81 -0
  29. package/module/plugins/react-query.js +1 -1
  30. package/module/plugins/recoil.js +1 -1
  31. package/module/plugins/types.js +1 -1
  32. package/module/utils/files.js +44 -0
  33. package/module/utils/unused.js +45 -0
  34. package/package.json +3 -3
  35. package/src/builder/builder.ts +36 -1
  36. package/src/generators/create-helpers.ts +28 -0
  37. package/src/helpers/contractContextBase.ts +92 -0
  38. package/src/helpers/contractsContextTSX.ts +73 -0
  39. package/src/helpers/index.ts +2 -0
  40. package/src/plugins/client.ts +30 -14
  41. package/src/plugins/message-composer.ts +23 -14
  42. package/src/plugins/msg-builder.ts +1 -1
  43. package/src/plugins/plugin-base.ts +30 -20
  44. package/src/plugins/provider-bundle.ts +97 -0
  45. package/src/plugins/provider.ts +114 -0
  46. package/src/plugins/react-query.ts +1 -1
  47. package/src/plugins/recoil.ts +1 -1
  48. package/src/plugins/types.ts +1 -1
  49. package/src/utils/files.ts +73 -0
  50. package/src/utils/unused.ts +52 -0
  51. package/types/src/builder/builder.d.ts +7 -1
  52. package/types/src/generators/create-helpers.d.ts +3 -0
  53. package/types/src/helpers/contractContextBase.d.ts +1 -0
  54. package/types/src/helpers/contractsContextTSX.d.ts +1 -0
  55. package/types/src/helpers/index.d.ts +2 -0
  56. package/types/src/plugins/client.d.ts +4 -3
  57. package/types/src/plugins/message-composer.d.ts +4 -3
  58. package/types/src/plugins/plugin-base.d.ts +7 -3
  59. package/types/src/plugins/provider-bundle.d.ts +13 -0
  60. package/types/src/plugins/provider.d.ts +15 -0
  61. package/types/src/plugins/use-contracts.d.ts +12 -0
  62. package/types/src/utils/files.d.ts +3 -0
  63. package/types/src/utils/unused.d.ts +5 -0
@@ -1,4 +1,4 @@
1
- import { RenderOptions, defaultOptions, RenderContext, ContractInfo, MessageComposerOptions} from "wasm-ast-types";
1
+ import { RenderOptions, defaultOptions, RenderContext, ContractInfo, MessageComposerOptions, BuilderContext} from "wasm-ast-types";
2
2
 
3
3
  import { header } from '../utils/header';
4
4
  import { join } from "path";
@@ -21,6 +21,9 @@ import { MsgBuilderPlugin } from "../plugins/msg-builder";
21
21
  import { MessageComposerPlugin } from "../plugins/message-composer";
22
22
  import { ClientPlugin } from "../plugins/client";
23
23
  import { TypesPlugin } from "../plugins/types";
24
+ import { ContractsContextProviderPlugin } from "../plugins/provider";
25
+ import { createHelpers } from "../generators/create-helpers";
26
+ import { ContractsProviderBundlePlugin } from "../plugins/provider-bundle";
24
27
 
25
28
  const defaultOpts: TSBuilderOptions = {
26
29
  bundle: {
@@ -44,8 +47,14 @@ export interface BundleOptions {
44
47
  bundlePath?: string;
45
48
  };
46
49
 
50
+ export interface UseContractsOptions {
51
+ enabled?: boolean;
52
+ filename?: string;
53
+ };
54
+
47
55
  export type TSBuilderOptions = {
48
56
  bundle?: BundleOptions;
57
+ useContracts?: UseContractsOptions;
49
58
  } & RenderOptions;
50
59
 
51
60
  export type BuilderFileType = 'type' | 'client' | 'recoil' | 'react-query' | 'message-composer' | 'msg-builder' | 'plugin';
@@ -83,6 +92,7 @@ export class TSBuilder {
83
92
  outPath: string;
84
93
  options?: TSBuilderOptions;
85
94
  plugins: IBuilderPlugin[] = [];
95
+ builderContext: BuilderContext = new BuilderContext();
86
96
 
87
97
  protected files: BuilderFile[] = [];
88
98
 
@@ -94,6 +104,7 @@ export class TSBuilder {
94
104
  new ReactQueryPlugin(this.options),
95
105
  new RecoilPlugin(this.options),
96
106
  new MsgBuilderPlugin(this.options),
107
+ new ContractsContextProviderPlugin(this.options),
97
108
  ]);
98
109
  }
99
110
 
@@ -113,6 +124,8 @@ export class TSBuilder {
113
124
  if (plugins && plugins.length) {
114
125
  [].push.apply(this.plugins, plugins);
115
126
  }
127
+
128
+ this.plugins.forEach(plugin=> plugin.setBuilder(this))
116
129
  }
117
130
 
118
131
  async build() {
@@ -147,6 +160,28 @@ export class TSBuilder {
147
160
  if (this.options.bundle.enabled) {
148
161
  this.bundle();
149
162
  }
163
+
164
+ //create useContracts bundle file
165
+ const contractsProviderBundlePlugin = new ContractsProviderBundlePlugin(this.options);
166
+ contractsProviderBundlePlugin.setBuilder(this);
167
+
168
+ let files = await contractsProviderBundlePlugin.render(
169
+ "",
170
+ {
171
+ schemas: [],
172
+ },
173
+ this.outPath
174
+ );
175
+ if(files && files.length){
176
+ [].push.apply(this.files, files);
177
+ }
178
+
179
+ createHelpers({
180
+ outPath: this.outPath,
181
+ contracts: this.contracts,
182
+ options: this.options,
183
+ plugins: this.plugins,
184
+ }, this.builderContext);
150
185
  }
151
186
 
152
187
  async bundle() {
@@ -0,0 +1,28 @@
1
+ import { join, dirname } from "path";
2
+ import { sync as mkdirp } from "mkdirp";
3
+ import pkg from "../../package.json";
4
+ import { writeContentToFile } from "../utils/files";
5
+ import { TSBuilderInput } from "../builder";
6
+ import { contractContextBase, contractsContextTSX } from "../helpers";
7
+ import { BuilderContext } from "wasm-ast-types";
8
+
9
+ const version = process.env.NODE_ENV === "test" ? "latest" : pkg.version;
10
+ const header = `/**
11
+ * This file and any referenced files were automatically generated by ${pkg.name}@${version}
12
+ * DO NOT MODIFY BY HAND. Instead, download the latest proto files for your chain
13
+ * and run the transpile command or yarn proto command to regenerate this bundle.
14
+ */
15
+ \n`;
16
+
17
+ const write = (outPath: string, file: string, content: string) => {
18
+ const outFile = join(outPath, file);
19
+ mkdirp(dirname(outFile));
20
+ writeContentToFile(outPath, header + content, outFile);
21
+ };
22
+
23
+ export const createHelpers = (input: TSBuilderInput, builderContext: BuilderContext) => {
24
+ if (input.options?.useContracts?.enabled && Object.keys(builderContext.providers)?.length) {
25
+ write(input.outPath, "contractContextBase.ts", contractContextBase);
26
+ write(input.outPath, "contracts-context.tsx", contractsContextTSX);
27
+ }
28
+ };
@@ -0,0 +1,92 @@
1
+ export const contractContextBase = `
2
+ import {
3
+ CosmWasmClient,
4
+ SigningCosmWasmClient,
5
+ } from '@cosmjs/cosmwasm-stargate';
6
+
7
+ export interface IContractConstructor {
8
+ address: string | undefined;
9
+ cosmWasmClient: CosmWasmClient | undefined;
10
+ signingCosmWasmClient: SigningCosmWasmClient | undefined;
11
+ }
12
+
13
+ export const NO_SINGING_ERROR_MESSAGE = 'signingCosmWasmClient not connected';
14
+
15
+ export const NO_COSMWASW_CLIENT_ERROR_MESSAGE = 'cosmWasmClient not connected';
16
+
17
+ export const NO_ADDRESS_ERROR_MESSAGE = "address doesn't exist";
18
+
19
+ export const NO_SIGNING_CLIENT_ERROR_MESSAGE =
20
+ 'Signing client is not generated. Please check ts-codegen config';
21
+
22
+ export const NO_QUERY_CLIENT_ERROR_MESSAGE =
23
+ 'Query client is not generated. Please check ts-codegen config';
24
+
25
+ export const NO_MESSAGE_COMPOSER_ERROR_MESSAGE =
26
+ 'Message composer client is not generated. Please check ts-codegen config';
27
+
28
+ /**
29
+ * a placeholder for non-generated classes
30
+ */
31
+ export interface IEmptyClient {}
32
+
33
+ export interface ISigningClientProvider<T> {
34
+ getSigningClient(contractAddr: string): T;
35
+ }
36
+
37
+ export interface IQueryClientProvider<T> {
38
+ getQueryClient(contractAddr: string): T;
39
+ }
40
+
41
+ export interface IMessageComposerProvider<T> {
42
+ getMessageComposer(contractAddr: string): T;
43
+ }
44
+
45
+ export class ContractBase<
46
+ TSign = IEmptyClient,
47
+ TQuery = IEmptyClient,
48
+ TMsgComposer = IEmptyClient
49
+ > {
50
+ constructor(
51
+ protected address: string | undefined,
52
+ protected cosmWasmClient: CosmWasmClient | undefined,
53
+ protected signingCosmWasmClient: SigningCosmWasmClient | undefined,
54
+ private TSign?: new (
55
+ client: SigningCosmWasmClient,
56
+ sender: string,
57
+ contractAddress: string
58
+ ) => TSign,
59
+ private TQuery?: new (
60
+ client: CosmWasmClient,
61
+ contractAddress: string
62
+ ) => TQuery,
63
+ private TMsgComposer?: new (
64
+ sender: string,
65
+ contractAddress: string
66
+ ) => TMsgComposer
67
+ ) {}
68
+
69
+ public getSigningClient(contractAddr: string): TSign {
70
+ if (!this.signingCosmWasmClient) throw new Error(NO_SINGING_ERROR_MESSAGE);
71
+ if (!this.address) throw new Error(NO_ADDRESS_ERROR_MESSAGE);
72
+ if (!this.TSign) throw new Error(NO_SIGNING_CLIENT_ERROR_MESSAGE);
73
+ return new this.TSign(
74
+ this.signingCosmWasmClient,
75
+ this.address,
76
+ contractAddr
77
+ );
78
+ }
79
+
80
+ public getQueryClient(contractAddr: string): TQuery {
81
+ if (!this.cosmWasmClient) throw new Error(NO_COSMWASW_CLIENT_ERROR_MESSAGE);
82
+ if (!this.TQuery) throw new Error(NO_QUERY_CLIENT_ERROR_MESSAGE);
83
+ return new this.TQuery(this.cosmWasmClient, contractAddr);
84
+ }
85
+
86
+ public getMessageComposer(contractAddr: string): TMsgComposer {
87
+ if (!this.address) throw new Error(NO_ADDRESS_ERROR_MESSAGE);
88
+ if (!this.TMsgComposer) throw new Error(NO_MESSAGE_COMPOSER_ERROR_MESSAGE);
89
+ return new this.TMsgComposer(this.address, contractAddr);
90
+ }
91
+ }
92
+ `;
@@ -0,0 +1,73 @@
1
+ export const contractsContextTSX = `
2
+ import React, { useEffect, useMemo, useRef, useState, useContext } from 'react';
3
+ import {
4
+ CosmWasmClient,
5
+ SigningCosmWasmClient,
6
+ } from '@cosmjs/cosmwasm-stargate';
7
+
8
+ import { IContractsContext, getProviders } from './contractContextProviders';
9
+
10
+ interface ContractsConfig {
11
+ address: string | undefined;
12
+ getCosmWasmClient: () => Promise<CosmWasmClient>;
13
+ getSigningCosmWasmClient: () => Promise<SigningCosmWasmClient>;
14
+ }
15
+
16
+ const ContractsContext = React.createContext<IContractsContext | null>(null);
17
+
18
+ export const ContractsProvider = ({
19
+ children,
20
+ contractsConfig,
21
+ }: {
22
+ children: React.ReactNode;
23
+ contractsConfig: ContractsConfig;
24
+ }) => {
25
+ const [cosmWasmClient, setCosmWasmClient] = useState<CosmWasmClient>();
26
+ const [signingCosmWasmClient, setSigningCosmWasmClient] =
27
+ useState<SigningCosmWasmClient>();
28
+
29
+ const { address, getCosmWasmClient, getSigningCosmWasmClient } =
30
+ contractsConfig;
31
+
32
+ const prevAddressRef = useRef<string | undefined>(address);
33
+
34
+ const contracts: IContractsContext = useMemo(() => {
35
+ return getProviders(address, cosmWasmClient, signingCosmWasmClient);
36
+ }, [address, cosmWasmClient, signingCosmWasmClient]);
37
+
38
+ useEffect(() => {
39
+ const connectSigningCwClient = async () => {
40
+ if (address && prevAddressRef.current !== address) {
41
+ const signingCosmWasmClient = await getSigningCosmWasmClient();
42
+ setSigningCosmWasmClient(signingCosmWasmClient);
43
+ } else if (!address) {
44
+ setSigningCosmWasmClient(undefined);
45
+ }
46
+ prevAddressRef.current = address;
47
+ };
48
+ connectSigningCwClient();
49
+ }, [address, getSigningCosmWasmClient]);
50
+
51
+ useEffect(() => {
52
+ const connectCosmWasmClient = async () => {
53
+ const cosmWasmClient = await getCosmWasmClient();
54
+ setCosmWasmClient(cosmWasmClient);
55
+ };
56
+ connectCosmWasmClient();
57
+ }, [getCosmWasmClient]);
58
+
59
+ return (
60
+ <ContractsContext.Provider value={contracts}>
61
+ {children}
62
+ </ContractsContext.Provider>
63
+ );
64
+ };
65
+
66
+ export const useContracts = () => {
67
+ const contracts = useContext(ContractsContext);
68
+ if (contracts === null) {
69
+ throw new Error('useContracts must be used within a ContractsProvider');
70
+ }
71
+ return contracts;
72
+ };
73
+ `;
@@ -0,0 +1,2 @@
1
+ export * from './contractContextBase';
2
+ export * from './contractsContextTSX';
@@ -1,22 +1,24 @@
1
- import { pascal } from 'case';
2
- import * as w from 'wasm-ast-types';
3
- import { findExecuteMsg, findAndParseTypes, findQueryMsg } from '../utils';
1
+ import { pascal } from "case";
2
+ import * as w from "wasm-ast-types";
3
+ import { findExecuteMsg, findAndParseTypes, findQueryMsg } from "../utils";
4
4
  import {
5
5
  RenderContext,
6
6
  ContractInfo,
7
7
  RenderContextBase,
8
8
  getMessageProperties,
9
- RenderOptions
10
- } from 'wasm-ast-types';
11
- import { BuilderFileType } from '../builder';
12
- import { BuilderPluginBase } from './plugin-base';
9
+ RenderOptions,
10
+ } from "wasm-ast-types";
11
+ import { BuilderFileType } from "../builder";
12
+ import { BuilderPluginBase } from "./plugin-base";
13
+
14
+ export const TYPE = "client";
13
15
 
14
16
  export class ClientPlugin extends BuilderPluginBase<RenderOptions> {
15
17
  initContext(
16
18
  contract: ContractInfo,
17
19
  options?: RenderOptions
18
20
  ): RenderContextBase<RenderOptions> {
19
- return new RenderContext(contract, options);
21
+ return new RenderContext(contract, options, this.builder.builderContext);
20
22
  }
21
23
 
22
24
  async doRender(
@@ -38,8 +40,8 @@ export class ClientPlugin extends BuilderPluginBase<RenderOptions> {
38
40
 
39
41
  const { schemas } = context.contract;
40
42
 
41
- const localname = pascal(name) + '.client.ts';
42
- const TypesFile = pascal(name) + '.types';
43
+ const localname = pascal(name) + ".client.ts";
44
+ const TypesFile = pascal(name) + ".types";
43
45
  const QueryMsg = findQueryMsg(schemas);
44
46
  const ExecuteMsg = findExecuteMsg(schemas);
45
47
  const typeHash = await findAndParseTypes(schemas);
@@ -62,6 +64,13 @@ export class ClientPlugin extends BuilderPluginBase<RenderOptions> {
62
64
  body.push(
63
65
  w.createQueryClass(context, QueryClient, ReadOnlyInstance, QueryMsg)
64
66
  );
67
+
68
+ context.addProviderInfo(
69
+ name,
70
+ w.PROVIDER_TYPES.QUERY_CLIENT_TYPE,
71
+ QueryClient,
72
+ localname
73
+ );
65
74
  }
66
75
 
67
76
  // execute messages
@@ -89,20 +98,27 @@ export class ClientPlugin extends BuilderPluginBase<RenderOptions> {
89
98
  ExecuteMsg
90
99
  )
91
100
  );
101
+
102
+ context.addProviderInfo(
103
+ name,
104
+ w.PROVIDER_TYPES.SIGNING_CLIENT_TYPE,
105
+ Client,
106
+ localname
107
+ );
92
108
  }
93
109
  }
94
110
 
95
- if (typeHash.hasOwnProperty('Coin')) {
111
+ if (typeHash.hasOwnProperty("Coin")) {
96
112
  // @ts-ignore
97
113
  delete context.utils.Coin;
98
114
  }
99
115
 
100
116
  return [
101
117
  {
102
- type: 'client',
118
+ type: TYPE,
103
119
  localname,
104
- body
105
- }
120
+ body,
121
+ },
106
122
  ];
107
123
  }
108
124
  }
@@ -1,23 +1,25 @@
1
- import { pascal } from 'case';
2
- import * as w from 'wasm-ast-types';
3
- import { findAndParseTypes, findExecuteMsg } from '../utils';
1
+ import { pascal } from "case";
2
+ import * as w from "wasm-ast-types";
3
+ import { findAndParseTypes, findExecuteMsg } from "../utils";
4
4
  import {
5
5
  MessageComposerOptions,
6
6
  getMessageProperties,
7
7
  ContractInfo,
8
8
  RenderContextBase,
9
9
  RenderContext,
10
- RenderOptions
11
- } from 'wasm-ast-types';
12
- import { BuilderFileType } from '../builder';
13
- import { BuilderPluginBase } from './plugin-base';
10
+ RenderOptions,
11
+ } from "wasm-ast-types";
12
+ import { BuilderFileType } from "../builder";
13
+ import { BuilderPluginBase } from "./plugin-base";
14
+
15
+ export const TYPE = "message-composer";
14
16
 
15
17
  export class MessageComposerPlugin extends BuilderPluginBase<RenderOptions> {
16
18
  initContext(
17
19
  contract: ContractInfo,
18
20
  options?: RenderOptions
19
21
  ): RenderContextBase<RenderOptions> {
20
- return new RenderContext(contract, options);
22
+ return new RenderContext(contract, options, this.builder.builderContext);
21
23
  }
22
24
 
23
25
  async doRender(
@@ -39,8 +41,8 @@ export class MessageComposerPlugin extends BuilderPluginBase<RenderOptions> {
39
41
 
40
42
  const { schemas } = context.contract;
41
43
 
42
- const localname = pascal(name) + '.message-composer.ts';
43
- const TypesFile = pascal(name) + '.types';
44
+ const localname = pascal(name) + ".message-composer.ts";
45
+ const TypesFile = pascal(name) + ".types";
44
46
  const ExecuteMsg = findExecuteMsg(schemas);
45
47
  const typeHash = await findAndParseTypes(schemas);
46
48
 
@@ -61,20 +63,27 @@ export class MessageComposerPlugin extends BuilderPluginBase<RenderOptions> {
61
63
  body.push(
62
64
  w.createMessageComposerClass(context, TheClass, Interface, ExecuteMsg)
63
65
  );
66
+
67
+ context.addProviderInfo(
68
+ name,
69
+ w.PROVIDER_TYPES.MESSAGE_COMPOSER_TYPE,
70
+ TheClass,
71
+ localname
72
+ );
64
73
  }
65
74
  }
66
75
 
67
- if (typeHash.hasOwnProperty('Coin')) {
76
+ if (typeHash.hasOwnProperty("Coin")) {
68
77
  // @ts-ignore
69
78
  delete context.utils.Coin;
70
79
  }
71
80
 
72
81
  return [
73
82
  {
74
- type: 'message-composer',
83
+ type: TYPE,
75
84
  localname,
76
- body
77
- }
85
+ body,
86
+ },
78
87
  ];
79
88
  }
80
89
  }
@@ -16,7 +16,7 @@ export class MsgBuilderPlugin extends BuilderPluginBase<RenderOptions> {
16
16
  contract: ContractInfo,
17
17
  options?: RenderOptions
18
18
  ): RenderContextBase<RenderOptions> {
19
- return new RenderContext(contract, options);
19
+ return new RenderContext(contract, options, this.builder.builderContext);
20
20
  }
21
21
 
22
22
  async doRender(
@@ -1,15 +1,16 @@
1
- import { sync as mkdirp } from 'mkdirp';
2
- import { join } from 'path';
3
- import { writeFileSync } from 'fs';
4
- import { header } from '../utils/header';
1
+ import { sync as mkdirp } from "mkdirp";
2
+ import { join } from "path";
3
+ import { writeFileSync } from "fs";
4
+ import { header } from "../utils/header";
5
+ import { ContractInfo, UtilMapping, IContext } from "wasm-ast-types";
6
+ import generate from "@babel/generator";
7
+ import * as t from "@babel/types";
5
8
  import {
6
- ContractInfo,
7
- UtilMapping,
8
- IContext
9
- } from 'wasm-ast-types';
10
- import generate from '@babel/generator';
11
- import * as t from '@babel/types';
12
- import { BuilderFile, BuilderFileType, TSBuilderOptions } from '../builder';
9
+ BuilderFile,
10
+ BuilderFileType,
11
+ TSBuilder,
12
+ TSBuilderOptions,
13
+ } from "../builder";
13
14
 
14
15
  /**
15
16
  * IBuilderPlugin is a common plugin that render generated code.
@@ -20,6 +21,10 @@ export interface IBuilderPlugin {
20
21
  */
21
22
  utils: UtilMapping;
22
23
 
24
+ builder?: TSBuilder;
25
+
26
+ setBuilder(builder: TSBuilder);
27
+
23
28
  /**
24
29
  * render generated cdoe.
25
30
  * @param name the name of contract
@@ -30,19 +35,27 @@ export interface IBuilderPlugin {
30
35
  render(
31
36
  name: string,
32
37
  contractInfo: ContractInfo,
33
- outPath: string,
38
+ outPath: string
34
39
  ): Promise<BuilderFile[]>;
35
40
  }
36
41
 
37
42
  /**
38
43
  * BuilderPluginBase enable ts-codegen users implement their own plugins by only implement a few functions.
39
44
  */
40
- export abstract class BuilderPluginBase<TOpt extends { enabled?: boolean }> implements IBuilderPlugin {
45
+ export abstract class BuilderPluginBase<TOpt extends { enabled?: boolean }>
46
+ implements IBuilderPlugin
47
+ {
48
+ builder?: TSBuilder;
41
49
  option: TOpt;
42
50
  utils: UtilMapping;
43
51
 
44
- constructor(opt: TOpt) {
52
+ constructor(opt: TOpt, builder?: TSBuilder) {
45
53
  this.option = opt;
54
+ this.builder = builder;
55
+ }
56
+
57
+ setBuilder(builder: TSBuilder) {
58
+ this.builder = builder;
46
59
  }
47
60
 
48
61
  async render(
@@ -65,7 +78,7 @@ export abstract class BuilderPluginBase<TOpt extends { enabled?: boolean }> impl
65
78
  }
66
79
 
67
80
  return results.map((result) => {
68
- const imports = context.getImports(this.utils);
81
+ const imports = context.getImports(this.utils, result.localname);
69
82
  const code =
70
83
  header + generate(t.program([...imports, ...result.body])).code;
71
84
 
@@ -78,7 +91,7 @@ export abstract class BuilderPluginBase<TOpt extends { enabled?: boolean }> impl
78
91
  pluginType: result.pluginType,
79
92
  contract: name,
80
93
  localname: result.localname,
81
- filename
94
+ filename,
82
95
  };
83
96
  });
84
97
  }
@@ -88,10 +101,7 @@ export abstract class BuilderPluginBase<TOpt extends { enabled?: boolean }> impl
88
101
  * @param contract
89
102
  * @param options
90
103
  */
91
- abstract initContext(
92
- contract: ContractInfo,
93
- options?: TOpt
94
- ): IContext;
104
+ abstract initContext(contract: ContractInfo, options?: TOpt): IContext;
95
105
 
96
106
  /**
97
107
  * render generated code here.
@@ -0,0 +1,97 @@
1
+ import { pascal } from "case";
2
+ import * as w from "wasm-ast-types";
3
+ import { ContractInfo, RenderContextBase, RenderContext } from "wasm-ast-types";
4
+ import { BuilderFileType, TSBuilderOptions } from "../builder";
5
+ import { BuilderPluginBase } from "./plugin-base";
6
+ import { GetLocalBaseNameByContractName } from "./provider";
7
+
8
+ export class ContractsProviderBundlePlugin extends BuilderPluginBase<TSBuilderOptions> {
9
+ constructor(opt: TSBuilderOptions) {
10
+ super(opt);
11
+
12
+ this.utils = {
13
+ CosmWasmClient: "@cosmjs/cosmwasm-stargate",
14
+ SigningCosmWasmClient: "@cosmjs/cosmwasm-stargate",
15
+ IQueryClientProvider: "__contractContextBase__",
16
+ ISigningClientProvider: "__contractContextBase__",
17
+ IMessageComposerProvider: "__contractContextBase__",
18
+ };
19
+ }
20
+
21
+ initContext(
22
+ contract: ContractInfo,
23
+ options?: TSBuilderOptions
24
+ ): RenderContextBase<TSBuilderOptions> {
25
+ return new RenderContext(contract, options, this.builder.builderContext);
26
+ }
27
+
28
+ async doRender(
29
+ name: string,
30
+ context: RenderContext
31
+ ): Promise<
32
+ {
33
+ type: BuilderFileType;
34
+ pluginType?: string;
35
+ localname: string;
36
+ body: any[];
37
+ }[]
38
+ > {
39
+ if (!this.option?.useContracts?.enabled) {
40
+ return;
41
+ }
42
+
43
+ const providerInfos = context.getProviderInfos();
44
+
45
+ if (!Object.keys(providerInfos)?.length) {
46
+ return;
47
+ }
48
+
49
+ const localname = "contractContextProviders.ts";
50
+
51
+ const body = [];
52
+
53
+ context.addUtil("CosmWasmClient");
54
+ context.addUtil("SigningCosmWasmClient");
55
+
56
+ context.addUtil("IQueryClientProvider");
57
+ context.addUtil("ISigningClientProvider");
58
+ context.addUtil("IMessageComposerProvider");
59
+
60
+ for (const name in providerInfos) {
61
+ if (Object.prototype.hasOwnProperty.call(providerInfos, name)) {
62
+ const providerInfo = providerInfos[name];
63
+
64
+ for (const key in providerInfo) {
65
+ if (Object.prototype.hasOwnProperty.call(providerInfo, key)) {
66
+ const info = providerInfo[key];
67
+
68
+ body.push(
69
+ w.importStmt(
70
+ [info.classname],
71
+ `./${info.basename}`
72
+ )
73
+ );
74
+ }
75
+ }
76
+
77
+ body.push(
78
+ w.importStmt(
79
+ [pascal(name)],
80
+ `./${GetLocalBaseNameByContractName(name)}`
81
+ )
82
+ );
83
+ }
84
+ }
85
+
86
+ body.push(w.createIContractsContext(providerInfos));
87
+ body.push(w.createGettingProviders(providerInfos));
88
+
89
+ return [
90
+ {
91
+ type: "plugin",
92
+ localname,
93
+ body,
94
+ },
95
+ ];
96
+ }
97
+ }