diff --git a/packages/api-contract/src/base/Code.ts b/packages/api-contract/src/base/Code.ts index baa8811f49..4c3afed520 100644 --- a/packages/api-contract/src/base/Code.ts +++ b/packages/api-contract/src/base/Code.ts @@ -10,7 +10,7 @@ import type { MapConstructorExec } from './types'; import { SubmittableResult } from '@polkadot/api'; import { ApiBase } from '@polkadot/api/base'; -import { assert, compactAddLength, isFunction, isUndefined, isWasm, stringCamelCase, u8aToU8a } from '@polkadot/util'; +import { assert, compactAddLength, isFunction, isUndefined, isWasm, logger, stringCamelCase, u8aToU8a } from '@polkadot/util'; import { blake2AsU8a } from '@polkadot/util-crypto'; import { Abi } from '../Abi'; @@ -20,6 +20,8 @@ import { Blueprint } from './Blueprint'; import { Contract } from './Contract'; import { createBluePrintTx, EMPTY_SALT, encodeSalt } from './util'; +const l = logger('api-contract/code'); + export class CodeSubmittableResult extends SubmittableResult { public readonly blueprint?: Blueprint; public readonly contract?: Contract; @@ -64,22 +66,26 @@ export class Code extends Base { * @deprecated Use the `code.tx.(...) format to put code and deploy */ public createContract (constructorOrId: AbiConstructor | string | number, options: BlueprintOptions, params: CodecArg[]): SubmittableExtrinsic> { + l.warn('.createContract is deprecated, use code.tx.(...) instead (where code refers to this instance)'); + return this.#instantiate(constructorOrId, options, params); } #instantiate = (constructorOrId: AbiConstructor | string | number, options: BlueprintOptions, params: CodecArg[]): SubmittableExtrinsic> => { return isFunction(this.api.tx.contracts.instantiateWithCode) - ? this.#instantiateSingle(constructorOrId, options, params) - : this.#instantiateBatch(constructorOrId, options, params); + ? this.#instantiateCurrent(constructorOrId, options, params) + : this.#instantiatePrev(constructorOrId, options, params); } - #instantiateSingle = (constructorOrId: AbiConstructor | string | number, { gasLimit = 0, salt, value = 0 }: BlueprintOptions, params: CodecArg[]): SubmittableExtrinsic> => { + #instantiateCurrent = (constructorOrId: AbiConstructor | string | number, { gasLimit = 0, salt, value = 0 }: BlueprintOptions, params: CodecArg[]): SubmittableExtrinsic> => { return this.api.tx.contracts .instantiateWithCode(value, gasLimit, compactAddLength(this.code), this.abi.findConstructor(constructorOrId).toU8a(params), encodeSalt(salt)) .withResultTransform(this.#transformEvents); } - #instantiateBatch = (constructorOrId: AbiConstructor | string | number, { gasLimit = 0, salt, value = 0 }: BlueprintOptions, params: CodecArg[]): SubmittableExtrinsic> => { + #instantiatePrev = (constructorOrId: AbiConstructor | string | number, { gasLimit = 0, salt, value = 0 }: BlueprintOptions, params: CodecArg[]): SubmittableExtrinsic> => { + assert(isFunction(this.api.tx.utility?.batch), 'Your chain does not include the utility pallet, for contracts v2 deployment, this is required'); + const encodedSalt = encodeSalt(salt); const withSalt = this.api.tx.contracts.instantiate.meta.args.length === 5; const encoded = this.abi.findConstructor(constructorOrId).toU8a(params, withSalt ? EMPTY_SALT : encodedSalt); diff --git a/packages/api-contract/src/base/Contract.ts b/packages/api-contract/src/base/Contract.ts index 670ac9c333..fa7dad95be 100644 --- a/packages/api-contract/src/base/Contract.ts +++ b/packages/api-contract/src/base/Contract.ts @@ -23,7 +23,8 @@ import { Base } from './Base'; // As per Rust, 5 * GAS_PER_SEC const MAX_CALL_GAS = new BN(5_000_000_000_000).subn(1); const ERROR_NO_CALL = 'Your node does not expose the contracts.call RPC. This is most probably due to a runtime configuration.'; -const l = logger('Contract'); + +const l = logger('api-contract/contract'); function createQuery (fn: (origin: string | AccountId | Uint8Array, options: ContractOptions, params: CodecArg[]) => ContractCallResult): ContractQuery { return (origin: string | AccountId | Uint8Array, options: BigInt | string | number | BN | ContractOptions, ...params: CodecArg[]): ContractCallResult => @@ -39,11 +40,14 @@ function createTx (fn: (options: ContractOptions, par : fn(...extractOptions(options, params)); } -function createWithId (fn: (messageOrId: AbiMessage | string | number, options: ContractOptions, params: CodecArg[]) => T): ContractGeneric { - return (messageOrId: AbiMessage | string | number, options: BigInt | string | number | BN | ContractOptions, ...params: CodecArg[]): T => - isOptions(options) +function createWithId (fn: (messageOrId: AbiMessage | string | number, options: ContractOptions, params: CodecArg[]) => T, warn?: string): ContractGeneric { + return (messageOrId: AbiMessage | string | number, options: BigInt | string | number | BN | ContractOptions, ...params: CodecArg[]): T => { + warn && l.warn(warn); + + return isOptions(options) ? fn(messageOrId, options, params) : fn(messageOrId, ...extractOptions(options, params)); + }; } export class ContractSubmittableResult extends SubmittableResult { @@ -109,8 +113,8 @@ export class Contract extends Base { super(api, abi, decorateMethod); this.address = this.registry.createType('AccountId', address); - this.exec = createWithId(this.#exec); - this.read = createWithId(this.#read); + this.exec = createWithId(this.#exec, '.exec is deprecated, use contract.tx.(...) instead (where contract refers to this instance)'); + this.read = createWithId(this.#read, '.read is deprecated, use contract.query.(...) instead (where contract refers to this instance)'); this.abi.messages.forEach((m): void => { const messageName = stringCamelCase(m.identifier);