soltag 0.0.3 → 0.0.4

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Abi, Hex } from 'viem';
1
+ import { Abi, Hex, Address } from 'viem';
2
2
 
3
3
  interface SolcAbiItem {
4
4
  type: string;
@@ -37,6 +37,8 @@ declare class SolCompilationError extends Error {
37
37
  constructor(errors: SolcDiagnostic[]);
38
38
  }
39
39
 
40
+ declare const CREATE2_FACTORY: Address;
41
+ declare const CREATE2_SALT: Hex;
40
42
  /**
41
43
  * Augment this interface via module augmentation to narrow the `abi` getter
42
44
  * for specific contract names. The generated `.soltag/types.d.ts` does this
@@ -72,7 +74,18 @@ declare class InlineContract<TName extends string = string> {
72
74
  * creation bytecode and deploy the contract normally instead.
73
75
  */
74
76
  get deployedBytecode(): Hex;
75
- get address(): Hex;
77
+ get address(): Address;
78
+ /**
79
+ * Convenience object for use with viem's `stateOverride` parameter.
80
+ *
81
+ * **Immutables caveat:** same as {@link deployedBytecode} — if the contract
82
+ * declares `immutable` variables assigned in the constructor, the slots will
83
+ * contain placeholder zeros and the override will not behave correctly.
84
+ */
85
+ get stateOverride(): {
86
+ address: Address;
87
+ code: Hex;
88
+ };
76
89
  bytecode(...args: unknown[]): Hex;
77
90
  }
78
91
 
@@ -113,4 +126,4 @@ declare class InlineContract<TName extends string = string> {
113
126
  */
114
127
  declare function sol<TName extends string>(name: TName): (strings: TemplateStringsArray, ...vals: string[]) => InlineContract<TName>;
115
128
 
116
- export { type CompilationResult, type CompiledContract, InlineContract, type InlineContractAbiMap, SolCompilationError, type SolcAbiItem, type SolcAbiParam, type SolcDiagnostic, sol };
129
+ export { CREATE2_FACTORY, CREATE2_SALT, type CompilationResult, type CompiledContract, InlineContract, type InlineContractAbiMap, SolCompilationError, type SolcAbiItem, type SolcAbiParam, type SolcDiagnostic, sol };
package/dist/index.js CHANGED
@@ -89,7 +89,9 @@ function toDiagnostics(errors) {
89
89
  }
90
90
 
91
91
  // src/runtime/contract.ts
92
- import { encodeAbiParameters, getAddress, keccak256 as keccak2562, slice } from "viem";
92
+ import { encodeAbiParameters, getContractAddress, zeroAddress } from "viem";
93
+ var CREATE2_FACTORY = "0x4e59b44847b379578588920cA78FbF26c0B4956C";
94
+ var CREATE2_SALT = `${zeroAddress}51A1E51A1E51A1E51A1E51A1`;
93
95
  var InlineContract = class _InlineContract {
94
96
  _source;
95
97
  _name;
@@ -146,10 +148,25 @@ var InlineContract = class _InlineContract {
146
148
  }
147
149
  get address() {
148
150
  if (!this._address) {
149
- this._address = getAddress(slice(keccak2562(this.deployedBytecode), 0, 20));
151
+ this._address = getContractAddress({
152
+ bytecode: this.ensureCompiled().bytecode,
153
+ from: CREATE2_FACTORY,
154
+ opcode: "CREATE2",
155
+ salt: CREATE2_SALT
156
+ });
150
157
  }
151
158
  return this._address;
152
159
  }
160
+ /**
161
+ * Convenience object for use with viem's `stateOverride` parameter.
162
+ *
163
+ * **Immutables caveat:** same as {@link deployedBytecode} — if the contract
164
+ * declares `immutable` variables assigned in the constructor, the slots will
165
+ * contain placeholder zeros and the override will not behave correctly.
166
+ */
167
+ get stateOverride() {
168
+ return { address: this.address, code: this.deployedBytecode };
169
+ }
153
170
  bytecode(...args) {
154
171
  const contract = this.ensureCompiled();
155
172
  if (args.length === 0) return contract.bytecode;
@@ -175,6 +192,8 @@ function sol(name) {
175
192
  };
176
193
  }
177
194
  export {
195
+ CREATE2_FACTORY,
196
+ CREATE2_SALT,
178
197
  InlineContract,
179
198
  SolCompilationError,
180
199
  sol
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime/compiler.ts","../src/solc.ts","../src/runtime/contract.ts","../src/runtime/sol.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nimport { type Abi, type Hex, keccak256, toHex } from \"viem\";\n\nimport {\n buildSolcInput,\n type SolcError,\n type SolcInputOptions,\n type SolcModule,\n type SolcStandardOutput,\n} from \"../solc.js\";\n\nconst require = createRequire(import.meta.url);\n\nlet solcInstance: SolcModule | undefined;\n\nfunction getSolc(): SolcModule {\n if (!solcInstance) {\n try {\n solcInstance = require(\"solc\") as SolcModule;\n } catch {\n throw new Error(\n \"solc is not installed. Install it (`pnpm add solc`) for runtime compilation, \" +\n \"or use the soltag bundler plugin for build-time compilation.\",\n );\n }\n }\n return solcInstance;\n}\n\nexport type { SolcAbiItem, SolcAbiParam } from \"../solc.js\";\n\nexport interface CompiledContract {\n abi: Abi;\n /** Runtime bytecode (what lives at the contract address). Used with stateOverride. */\n deployedBytecode: Hex;\n /** Init bytecode (constructor + deployment code). Used for actual deployment. */\n bytecode: Hex;\n}\n\nexport type CompilationResult = Record<string, CompiledContract>;\n\nexport interface SolcDiagnostic {\n severity: \"error\" | \"warning\";\n message: string;\n formattedMessage: string;\n sourceLocation?: {\n file: string;\n start: number;\n end: number;\n };\n}\n\nexport class SolCompilationError extends Error {\n constructor(public readonly errors: SolcDiagnostic[]) {\n const formatted = errors.map((e) => `${e.severity}: ${e.message}`).join(\"\\n\");\n super(`Solidity compilation failed:\\n${formatted}`);\n this.name = \"SolCompilationError\";\n }\n}\n\n// Cache compiled results by source hash\nconst compilationCache = new Map<string, CompilationResult>();\n\nexport function hashSource(source: string, options?: SolcInputOptions): Hex {\n return keccak256(toHex(source + JSON.stringify(options ?? {})));\n}\n\nexport function compile(source: string, options?: SolcInputOptions): CompilationResult {\n const hash = hashSource(source, options);\n const cached = compilationCache.get(hash);\n if (cached) return cached;\n\n const solc = getSolc();\n const input = buildSolcInput(source, options);\n const rawOutput = solc.compile(JSON.stringify(input));\n const output = JSON.parse(rawOutput) as SolcStandardOutput;\n\n const diagnostics = toDiagnostics(output.errors);\n const errors = diagnostics.filter((d) => d.severity === \"error\");\n if (errors.length > 0) {\n throw new SolCompilationError(errors);\n }\n\n const result: CompilationResult = {};\n\n if (output.contracts) {\n for (const [, fileContracts] of Object.entries(output.contracts)) {\n for (const [contractName, contractOutput] of Object.entries(fileContracts)) {\n result[contractName] = {\n abi: contractOutput.abi as Abi,\n deployedBytecode: `0x${contractOutput.evm.deployedBytecode.object}` as Hex,\n bytecode: `0x${contractOutput.evm.bytecode.object}` as Hex,\n };\n }\n }\n }\n\n compilationCache.set(hash, result);\n return result;\n}\n\nfunction toDiagnostics(errors: SolcError[] | undefined): SolcDiagnostic[] {\n return (errors ?? []).map((e) => ({\n severity: e.severity as \"error\" | \"warning\",\n message: e.message,\n formattedMessage: e.formattedMessage,\n sourceLocation: e.sourceLocation,\n }));\n}\n","/**\n * Shared solc-js types and helpers used by both the runtime compiler\n * and the LS plugin cache.\n */\n\nexport interface SolcModule {\n compile(input: string): string;\n}\n\n/**\n * Build the standard JSON input object for solc.\n */\nexport interface SolcInputOptions {\n optimizer?: {\n enabled?: boolean;\n runs?: number;\n };\n}\n\nexport function buildSolcInput(source: string, options?: SolcInputOptions) {\n return {\n language: \"Solidity\" as const,\n sources: {\n \"inline.sol\": { content: source },\n },\n settings: {\n optimizer: {\n enabled: options?.optimizer?.enabled ?? true,\n runs: options?.optimizer?.runs ?? 1,\n },\n outputSelection: {\n \"*\": {\n \"*\": [\"abi\", \"evm.bytecode.object\", \"evm.deployedBytecode.object\"],\n },\n },\n },\n };\n}\n\n// --- solc standard output types ---\n\nexport interface SolcStandardOutput {\n contracts?: Record<string, Record<string, SolcContractOutput>>;\n errors?: SolcError[];\n}\n\nexport interface SolcContractOutput {\n abi: SolcAbiItem[];\n evm: {\n bytecode: { object: string };\n deployedBytecode: { object: string };\n };\n}\n\nexport interface SolcAbiItem {\n type: string;\n name?: string;\n inputs?: SolcAbiParam[];\n outputs?: SolcAbiParam[];\n stateMutability?: string;\n}\n\nexport interface SolcAbiParam {\n name: string;\n type: string;\n components?: SolcAbiParam[];\n internalType?: string;\n}\n\nexport interface SolcError {\n severity: string;\n message: string;\n formattedMessage: string;\n sourceLocation?: {\n file: string;\n start: number;\n end: number;\n };\n}\n","import { type Abi, encodeAbiParameters, getAddress, type Hex, keccak256, slice } from \"viem\";\n\nimport { type CompilationResult, type CompiledContract, compile } from \"./compiler.js\";\n\n/**\n * Augment this interface via module augmentation to narrow the `abi` getter\n * for specific contract names. The generated `.soltag/types.d.ts` does this\n * automatically.\n */\n// biome-ignore lint/suspicious/noEmptyInterface: augmented by generated .d.ts\nexport interface InlineContractAbiMap {}\n\nexport class InlineContract<TName extends string = string> {\n private _source: string;\n private _name: TName;\n private _compiled: CompilationResult | undefined;\n private _contract: CompiledContract | undefined;\n private _address: Hex | undefined;\n\n constructor(source: string, name: TName) {\n this._source = source;\n this._name = name;\n }\n\n /**\n * Create a InlineContract from pre-compiled artifacts.\n * Used by the bundler plugin to bypass runtime solc compilation.\n */\n static fromArtifacts<T extends string>(name: T, artifacts: CompilationResult): InlineContract<T> {\n const instance = new InlineContract(\"\", name);\n instance._compiled = artifacts;\n return instance as InlineContract<T>;\n }\n\n private ensureCompiled(): CompiledContract {\n if (!this._contract) {\n if (!this._compiled) {\n this._compiled = compile(this._source);\n }\n const contract = this._compiled[this._name];\n if (!contract) {\n const available = Object.keys(this._compiled).join(\", \");\n throw new Error(`Contract \"${this._name}\" not found in compilation result. Available contracts: ${available}`);\n }\n this._contract = contract;\n }\n return this._contract;\n }\n\n get name(): TName {\n return this._name;\n }\n\n get abi(): TName extends keyof InlineContractAbiMap ? InlineContractAbiMap[TName] : Abi {\n return this.ensureCompiled().abi as TName extends keyof InlineContractAbiMap ? InlineContractAbiMap[TName] : Abi;\n }\n\n /**\n * The runtime bytecode of the named contract, as emitted by solc.\n *\n * **Immutables caveat:** If the contract declares `immutable` variables that\n * are assigned in the constructor, solc emits placeholder zeros in their\n * slots. The real values are only filled in during actual deployment (the\n * constructor runs and writes them into the runtime code). This means\n * `deployedBytecode` is unsuitable for `stateOverride` injection when the\n * contract relies on immutables — the zeroed slots will cause unexpected\n * behavior. In those cases, use `bytecode(…constructorArgs)` to get the\n * creation bytecode and deploy the contract normally instead.\n */\n get deployedBytecode(): Hex {\n return this.ensureCompiled().deployedBytecode;\n }\n\n get address(): Hex {\n if (!this._address) {\n this._address = getAddress(slice(keccak256(this.deployedBytecode), 0, 20));\n }\n return this._address;\n }\n\n bytecode(...args: unknown[]): Hex {\n const contract = this.ensureCompiled();\n if (args.length === 0) return contract.bytecode;\n\n const constructorAbi = contract.abi.find(\n (item): item is Extract<typeof item, { type: \"constructor\" }> => \"type\" in item && item.type === \"constructor\",\n );\n if (\n !constructorAbi ||\n !(\"inputs\" in constructorAbi) ||\n !constructorAbi.inputs ||\n constructorAbi.inputs.length === 0\n ) {\n throw new Error(`Contract \"${this._name}\" does not have a constructor that accepts arguments`);\n }\n\n const encoded = encodeAbiParameters(constructorAbi.inputs, args);\n return `${contract.bytecode}${encoded.slice(2)}` as Hex;\n }\n}\n","import { InlineContract } from \"./contract.js\";\n\n/**\n * Factory for creating inline Solidity contracts with per-contract type narrowing.\n *\n * Usage:\n * ```ts\n * const lens = sol(\"Lens\")`\n * pragma solidity ^0.8.24;\n * contract Lens {\n * function getBalance(address token, address user) external view returns (uint256) {\n * return IERC20(token).balanceOf(user);\n * }\n * }\n * `;\n *\n * lens.name; // \"Lens\"\n * lens.address; // deterministic address\n * lens.abi; // Lens contract's ABI\n * lens.deployedBytecode; // runtime bytecode\n * lens.bytecode(); // creation bytecode\n * ```\n *\n * String interpolation is supported for composing Solidity from reusable fragments:\n * ```ts\n * const IERC20 = `\n * interface IERC20 {\n * function balanceOf(address) external view returns (uint256);\n * }\n * `;\n *\n * const lens = sol(\"Lens\")`\n * ${IERC20}\n * contract Lens { ... }\n * `;\n * ```\n */\nexport function sol<TName extends string>(name: TName) {\n return (strings: TemplateStringsArray, ...vals: string[]): InlineContract<TName> => {\n let source = strings[0];\n for (let i = 0; i < vals.length; i++) {\n source += vals[i] + strings[i + 1];\n }\n return new InlineContract(source, name);\n };\n}\n"],"mappings":"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","names":["require","keccak256","keccak256"]}
1
+ {"version":3,"sources":["../src/runtime/compiler.ts","../src/solc.ts","../src/runtime/contract.ts","../src/runtime/sol.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nimport { type Abi, type Hex, keccak256, toHex } from \"viem\";\n\nimport {\n buildSolcInput,\n type SolcError,\n type SolcInputOptions,\n type SolcModule,\n type SolcStandardOutput,\n} from \"../solc.js\";\n\nconst require = createRequire(import.meta.url);\n\nlet solcInstance: SolcModule | undefined;\n\nfunction getSolc(): SolcModule {\n if (!solcInstance) {\n try {\n solcInstance = require(\"solc\") as SolcModule;\n } catch {\n throw new Error(\n \"solc is not installed. Install it (`pnpm add solc`) for runtime compilation, \" +\n \"or use the soltag bundler plugin for build-time compilation.\",\n );\n }\n }\n return solcInstance;\n}\n\nexport type { SolcAbiItem, SolcAbiParam } from \"../solc.js\";\n\nexport interface CompiledContract {\n abi: Abi;\n /** Runtime bytecode (what lives at the contract address). Used with stateOverride. */\n deployedBytecode: Hex;\n /** Init bytecode (constructor + deployment code). Used for actual deployment. */\n bytecode: Hex;\n}\n\nexport type CompilationResult = Record<string, CompiledContract>;\n\nexport interface SolcDiagnostic {\n severity: \"error\" | \"warning\";\n message: string;\n formattedMessage: string;\n sourceLocation?: {\n file: string;\n start: number;\n end: number;\n };\n}\n\nexport class SolCompilationError extends Error {\n constructor(public readonly errors: SolcDiagnostic[]) {\n const formatted = errors.map((e) => `${e.severity}: ${e.message}`).join(\"\\n\");\n super(`Solidity compilation failed:\\n${formatted}`);\n this.name = \"SolCompilationError\";\n }\n}\n\n// Cache compiled results by source hash\nconst compilationCache = new Map<string, CompilationResult>();\n\nexport function hashSource(source: string, options?: SolcInputOptions): Hex {\n return keccak256(toHex(source + JSON.stringify(options ?? {})));\n}\n\nexport function compile(source: string, options?: SolcInputOptions): CompilationResult {\n const hash = hashSource(source, options);\n const cached = compilationCache.get(hash);\n if (cached) return cached;\n\n const solc = getSolc();\n const input = buildSolcInput(source, options);\n const rawOutput = solc.compile(JSON.stringify(input));\n const output = JSON.parse(rawOutput) as SolcStandardOutput;\n\n const diagnostics = toDiagnostics(output.errors);\n const errors = diagnostics.filter((d) => d.severity === \"error\");\n if (errors.length > 0) {\n throw new SolCompilationError(errors);\n }\n\n const result: CompilationResult = {};\n\n if (output.contracts) {\n for (const [, fileContracts] of Object.entries(output.contracts)) {\n for (const [contractName, contractOutput] of Object.entries(fileContracts)) {\n result[contractName] = {\n abi: contractOutput.abi as Abi,\n deployedBytecode: `0x${contractOutput.evm.deployedBytecode.object}` as Hex,\n bytecode: `0x${contractOutput.evm.bytecode.object}` as Hex,\n };\n }\n }\n }\n\n compilationCache.set(hash, result);\n return result;\n}\n\nfunction toDiagnostics(errors: SolcError[] | undefined): SolcDiagnostic[] {\n return (errors ?? []).map((e) => ({\n severity: e.severity as \"error\" | \"warning\",\n message: e.message,\n formattedMessage: e.formattedMessage,\n sourceLocation: e.sourceLocation,\n }));\n}\n","/**\n * Shared solc-js types and helpers used by both the runtime compiler\n * and the LS plugin cache.\n */\n\nexport interface SolcModule {\n compile(input: string): string;\n}\n\n/**\n * Build the standard JSON input object for solc.\n */\nexport interface SolcInputOptions {\n optimizer?: {\n enabled?: boolean;\n runs?: number;\n };\n}\n\nexport function buildSolcInput(source: string, options?: SolcInputOptions) {\n return {\n language: \"Solidity\" as const,\n sources: {\n \"inline.sol\": { content: source },\n },\n settings: {\n optimizer: {\n enabled: options?.optimizer?.enabled ?? true,\n runs: options?.optimizer?.runs ?? 1,\n },\n outputSelection: {\n \"*\": {\n \"*\": [\"abi\", \"evm.bytecode.object\", \"evm.deployedBytecode.object\"],\n },\n },\n },\n };\n}\n\n// --- solc standard output types ---\n\nexport interface SolcStandardOutput {\n contracts?: Record<string, Record<string, SolcContractOutput>>;\n errors?: SolcError[];\n}\n\nexport interface SolcContractOutput {\n abi: SolcAbiItem[];\n evm: {\n bytecode: { object: string };\n deployedBytecode: { object: string };\n };\n}\n\nexport interface SolcAbiItem {\n type: string;\n name?: string;\n inputs?: SolcAbiParam[];\n outputs?: SolcAbiParam[];\n stateMutability?: string;\n}\n\nexport interface SolcAbiParam {\n name: string;\n type: string;\n components?: SolcAbiParam[];\n internalType?: string;\n}\n\nexport interface SolcError {\n severity: string;\n message: string;\n formattedMessage: string;\n sourceLocation?: {\n file: string;\n start: number;\n end: number;\n };\n}\n","import { type Abi, type Address, encodeAbiParameters, getContractAddress, type Hex, zeroAddress } from \"viem\";\n\nimport { type CompilationResult, type CompiledContract, compile } from \"./compiler.js\";\n\nexport const CREATE2_FACTORY: Address = \"0x4e59b44847b379578588920cA78FbF26c0B4956C\";\nexport const CREATE2_SALT: Hex = `${zeroAddress}51A1E51A1E51A1E51A1E51A1`;\n\n/**\n * Augment this interface via module augmentation to narrow the `abi` getter\n * for specific contract names. The generated `.soltag/types.d.ts` does this\n * automatically.\n */\n// biome-ignore lint/suspicious/noEmptyInterface: augmented by generated .d.ts\nexport interface InlineContractAbiMap {}\n\nexport class InlineContract<TName extends string = string> {\n private _source: string;\n private _name: TName;\n private _compiled: CompilationResult | undefined;\n private _contract: CompiledContract | undefined;\n private _address: Address | undefined;\n\n constructor(source: string, name: TName) {\n this._source = source;\n this._name = name;\n }\n\n /**\n * Create a InlineContract from pre-compiled artifacts.\n * Used by the bundler plugin to bypass runtime solc compilation.\n */\n static fromArtifacts<T extends string>(name: T, artifacts: CompilationResult): InlineContract<T> {\n const instance = new InlineContract(\"\", name);\n instance._compiled = artifacts;\n return instance as InlineContract<T>;\n }\n\n private ensureCompiled(): CompiledContract {\n if (!this._contract) {\n if (!this._compiled) {\n this._compiled = compile(this._source);\n }\n const contract = this._compiled[this._name];\n if (!contract) {\n const available = Object.keys(this._compiled).join(\", \");\n throw new Error(`Contract \"${this._name}\" not found in compilation result. Available contracts: ${available}`);\n }\n this._contract = contract;\n }\n return this._contract;\n }\n\n get name(): TName {\n return this._name;\n }\n\n get abi(): TName extends keyof InlineContractAbiMap ? InlineContractAbiMap[TName] : Abi {\n return this.ensureCompiled().abi as TName extends keyof InlineContractAbiMap ? InlineContractAbiMap[TName] : Abi;\n }\n\n /**\n * The runtime bytecode of the named contract, as emitted by solc.\n *\n * **Immutables caveat:** If the contract declares `immutable` variables that\n * are assigned in the constructor, solc emits placeholder zeros in their\n * slots. The real values are only filled in during actual deployment (the\n * constructor runs and writes them into the runtime code). This means\n * `deployedBytecode` is unsuitable for `stateOverride` injection when the\n * contract relies on immutables — the zeroed slots will cause unexpected\n * behavior. In those cases, use `bytecode(…constructorArgs)` to get the\n * creation bytecode and deploy the contract normally instead.\n */\n get deployedBytecode(): Hex {\n return this.ensureCompiled().deployedBytecode;\n }\n\n get address(): Address {\n if (!this._address) {\n this._address = getContractAddress({\n bytecode: this.ensureCompiled().bytecode,\n from: CREATE2_FACTORY,\n opcode: \"CREATE2\",\n salt: CREATE2_SALT,\n });\n }\n return this._address;\n }\n\n /**\n * Convenience object for use with viem's `stateOverride` parameter.\n *\n * **Immutables caveat:** same as {@link deployedBytecode} — if the contract\n * declares `immutable` variables assigned in the constructor, the slots will\n * contain placeholder zeros and the override will not behave correctly.\n */\n get stateOverride(): { address: Address; code: Hex } {\n return { address: this.address, code: this.deployedBytecode };\n }\n\n bytecode(...args: unknown[]): Hex {\n const contract = this.ensureCompiled();\n if (args.length === 0) return contract.bytecode;\n\n const constructorAbi = contract.abi.find(\n (item): item is Extract<typeof item, { type: \"constructor\" }> => \"type\" in item && item.type === \"constructor\",\n );\n if (\n !constructorAbi ||\n !(\"inputs\" in constructorAbi) ||\n !constructorAbi.inputs ||\n constructorAbi.inputs.length === 0\n ) {\n throw new Error(`Contract \"${this._name}\" does not have a constructor that accepts arguments`);\n }\n\n const encoded = encodeAbiParameters(constructorAbi.inputs, args);\n return `${contract.bytecode}${encoded.slice(2)}` as Hex;\n }\n}\n","import { InlineContract } from \"./contract.js\";\n\n/**\n * Factory for creating inline Solidity contracts with per-contract type narrowing.\n *\n * Usage:\n * ```ts\n * const lens = sol(\"Lens\")`\n * pragma solidity ^0.8.24;\n * contract Lens {\n * function getBalance(address token, address user) external view returns (uint256) {\n * return IERC20(token).balanceOf(user);\n * }\n * }\n * `;\n *\n * lens.name; // \"Lens\"\n * lens.address; // deterministic address\n * lens.abi; // Lens contract's ABI\n * lens.deployedBytecode; // runtime bytecode\n * lens.bytecode(); // creation bytecode\n * ```\n *\n * String interpolation is supported for composing Solidity from reusable fragments:\n * ```ts\n * const IERC20 = `\n * interface IERC20 {\n * function balanceOf(address) external view returns (uint256);\n * }\n * `;\n *\n * const lens = sol(\"Lens\")`\n * ${IERC20}\n * contract Lens { ... }\n * `;\n * ```\n */\nexport function sol<TName extends string>(name: TName) {\n return (strings: TemplateStringsArray, ...vals: string[]): InlineContract<TName> => {\n let source = strings[0];\n for (let i = 0; i < vals.length; i++) {\n source += vals[i] + strings[i + 1];\n }\n return new InlineContract(source, name);\n };\n}\n"],"mappings":"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","names":["require"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "soltag",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Inline Solidity tagged template for TypeScript with IDE type inference",
5
5
  "license": "MIT",
6
6
  "keywords": [