diff --git a/package.json b/package.json index e836db8..837e312 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stellar-plus", - "version": "0.12.0", + "version": "0.12.1", "description": "beta version of stellar-plus, an all-in-one sdk for the Stellar blockchain", "main": "./lib/index.js", "types": "./lib/index.d.ts", diff --git a/src/stellar-plus/asset/classic/index.ts b/src/stellar-plus/asset/classic/index.ts index 0673f6b..ca45554 100644 --- a/src/stellar-plus/asset/classic/index.ts +++ b/src/stellar-plus/asset/classic/index.ts @@ -11,6 +11,7 @@ import { import { AccountHandler } from 'stellar-plus/account/account-handler/types' import { + BaseInvocation, ClassicAssetHandlerConstructorArgs, ControlFlags, ClassicAssetHandler as IClassicAssetHandler, @@ -19,7 +20,7 @@ import { AssetTypes } from 'stellar-plus/asset/types' import { ClassicTransactionPipeline } from 'stellar-plus/core/pipelines/classic-transaction' import { ClassicTransactionPipelineOptions, - ClassicTransactionPipelineOutputSimple, + ClassicTransactionPipelineOutput, } from 'stellar-plus/core/pipelines/classic-transaction/types' import { TransactionInvocation } from 'stellar-plus/core/types' import { HorizonHandlerClient as HorizonHandler } from 'stellar-plus/horizon' @@ -157,7 +158,9 @@ export class ClassicAssetHandler implements IClassicAssetHandler { * * @description - Transfers the given amount of the asset from the 'from' account to the 'to' account. */ - public async transfer(args: { from: string; to: string; amount: number } & TransactionInvocation): Promise { + public async transfer( + args: { from: string; to: string; amount: number } & BaseInvocation + ): Promise { const { from, to, amount } = args const txInvocation = args as TransactionInvocation @@ -169,12 +172,15 @@ export class ClassicAssetHandler implements IClassicAssetHandler { source: from, }) - await this.classicTransactionPipeline.execute({ + const result = await this.classicTransactionPipeline.execute({ txInvocation, operations: [transferOp], + options: { + ...args.options, + }, }) - return + return result } /** @@ -189,7 +195,9 @@ export class ClassicAssetHandler implements IClassicAssetHandler { * * @description - Burns the given amount of the asset from the 'from' account. */ - public async burn(args: { from: string; amount: number } & TransactionInvocation): Promise { + public async burn( + args: { from: string; amount: number } & BaseInvocation + ): Promise { if (this.type === AssetTypes.native) { throw "You can't burn XLM" } @@ -225,8 +233,8 @@ export class ClassicAssetHandler implements IClassicAssetHandler { args: { to: string amount: number - } & TransactionInvocation - ): Promise { + } & BaseInvocation + ): Promise { this.requireIssuerAccount() // Enforces the issuer account to be set. const { to, amount } = args @@ -244,19 +252,31 @@ export class ClassicAssetHandler implements IClassicAssetHandler { source: this.asset.getIssuer(), }) - const result = (await this.classicTransactionPipeline.execute({ + const result = await this.classicTransactionPipeline.execute({ txInvocation: updatedTxInvocation, operations: [mintOp], - })) as ClassicTransactionPipelineOutputSimple + options: { + ...args.options, + }, + }) - return result.response + return result } + /** + * + * @param {ControlFlags} controlFlags - The control flags to set for the asset. + * @param {TransactionInvocation} txInvocation - The transaction invocation object spread. The Issuer account will be automatically added as a signer. + * + * @requires - The issuer account to be set in the asset. + * + * @returns {ClassicTransactionPipelineOutput} The response from the Horizon server. + */ public async setFlags( args: { controlFlags: ControlFlags - } & TransactionInvocation - ): Promise { + } & BaseInvocation + ): Promise { this.requireIssuerAccount() // Enforces the issuer account to be set. const { controlFlags } = args @@ -278,12 +298,15 @@ export class ClassicAssetHandler implements IClassicAssetHandler { source: this.asset.getIssuer(), }) - const result = (await this.classicTransactionPipeline.execute({ + const result = await this.classicTransactionPipeline.execute({ txInvocation: updatedTxInvocation, operations: [setFlags], - })) as ClassicTransactionPipelineOutputSimple + options: { + ...args.options, + }, + }) - return result.response + return result } public async clawback(): Promise { @@ -313,8 +336,8 @@ export class ClassicAssetHandler implements IClassicAssetHandler { args: { to: string amount: number - } & TransactionInvocation - ): Promise { + } & BaseInvocation + ): Promise { this.requireIssuerAccount() // Enforces the issuer account to be set. const { to, amount } = args @@ -337,12 +360,15 @@ export class ClassicAssetHandler implements IClassicAssetHandler { source: this.asset.getIssuer(), }) - const result = (await this.classicTransactionPipeline.execute({ + const result = await this.classicTransactionPipeline.execute({ txInvocation: updatedTxInvocation, operations: [addTrustlineOp, mintOp], - })) as ClassicTransactionPipelineOutputSimple + options: { + ...args.options, + }, + }) - return result.response + return result } /** @@ -359,8 +385,8 @@ export class ClassicAssetHandler implements IClassicAssetHandler { public async addTrustline( args: { to: string - } & TransactionInvocation - ): Promise { + } & BaseInvocation + ): Promise { const { to } = args const txInvocation = args as TransactionInvocation @@ -370,12 +396,15 @@ export class ClassicAssetHandler implements IClassicAssetHandler { asset: this.asset, }) - const result = (await this.classicTransactionPipeline.execute({ + const result = await this.classicTransactionPipeline.execute({ txInvocation, operations: [addTrustlineOp], - })) as ClassicTransactionPipelineOutputSimple + options: { + ...args.options, + }, + }) - return result.response + return result } //========================================== diff --git a/src/stellar-plus/asset/classic/index.unit.test.ts b/src/stellar-plus/asset/classic/index.unit.test.ts index 29dc21d..b06bd00 100644 --- a/src/stellar-plus/asset/classic/index.unit.test.ts +++ b/src/stellar-plus/asset/classic/index.unit.test.ts @@ -283,6 +283,7 @@ describe('Classic Asset Handler', () => { expect(spyExecute).toHaveBeenCalledExactlyOnceWith({ txInvocation: args as TransactionInvocation, operations: ['paymentOp'], + options: {}, }) }) @@ -341,6 +342,7 @@ describe('Classic Asset Handler', () => { signers: [mockedUserAccountHandler, mockedIssuerAccountHandler], } as TransactionInvocation, operations: ['paymentOp'], + options: {}, }) }) @@ -366,6 +368,7 @@ describe('Classic Asset Handler', () => { expect(spyExecute).toHaveBeenCalledExactlyOnceWith({ txInvocation: args as TransactionInvocation, operations: ['changeTrustOp'], + options: {}, }) }) @@ -396,6 +399,7 @@ describe('Classic Asset Handler', () => { signers: [mockedUserAccountHandler, mockedIssuerAccountHandler], } as TransactionInvocation, operations: ['changeTrustOp', 'paymentOp'], + options: {}, }) }) }) diff --git a/src/stellar-plus/asset/classic/types.ts b/src/stellar-plus/asset/classic/types.ts index 1eb7487..3dfdb8b 100644 --- a/src/stellar-plus/asset/classic/types.ts +++ b/src/stellar-plus/asset/classic/types.ts @@ -1,8 +1,10 @@ -import { Horizon } from '@stellar/stellar-sdk' - import { AccountHandler } from 'stellar-plus/account/account-handler/types' import { AssetType, AssetTypes } from 'stellar-plus/asset/types' -import { ClassicTransactionPipelineOptions } from 'stellar-plus/core/pipelines/classic-transaction/types' +import { + ClassicTransactionPipelineInput, + ClassicTransactionPipelineOptions, + ClassicTransactionPipelineOutput, +} from 'stellar-plus/core/pipelines/classic-transaction/types' import { TransactionInvocation } from 'stellar-plus/core/types' import { NetworkConfig } from 'stellar-plus/types' @@ -31,18 +33,18 @@ export type ClassicTokenInterfaceManagement = { args: { to: string amount: number - } & TransactionInvocation - ) => Promise + } & BaseInvocation + ) => Promise - setFlags: ( - args: { controlFlags: ControlFlags } & TransactionInvocation - ) => Promise + setFlags: (args: { controlFlags: ControlFlags } & BaseInvocation) => Promise } export type ClassicTokenInterfaceUser = { balance: (id: string) => Promise - transfer: (args: { from: string; to: string; amount: number } & TransactionInvocation) => Promise - burn: (args: { from: string; amount: number } & TransactionInvocation) => Promise + transfer: ( + args: { from: string; to: string; amount: number } & BaseInvocation + ) => Promise + burn: (args: { from: string; amount: number } & BaseInvocation) => Promise decimals: () => Promise name: () => Promise symbol: () => Promise @@ -50,8 +52,9 @@ export type ClassicTokenInterfaceUser = { export type ClassicUtils = { addTrustlineAndMint: ( - args: { to: string; amount: number } & TransactionInvocation - ) => Promise + args: { to: string; amount: number } & BaseInvocation + ) => Promise + addTrustline: (args: { to: string } & BaseInvocation) => Promise } export type ControlFlags = { @@ -60,3 +63,7 @@ export type ControlFlags = { clawbackEnabled?: boolean authorizationImmutable?: boolean } + +export type BaseInvocation = TransactionInvocation & { + options?: ClassicTransactionPipelineInput['options'] +} diff --git a/src/stellar-plus/core/contract-engine/index.ts b/src/stellar-plus/core/contract-engine/index.ts index 9a8a6b1..6c877d2 100644 --- a/src/stellar-plus/core/contract-engine/index.ts +++ b/src/stellar-plus/core/contract-engine/index.ts @@ -13,6 +13,7 @@ import { Spec } from '@stellar/stellar-sdk/contract' import { CEError } from 'stellar-plus/core/contract-engine/errors' import { + BaseInvocation, ContractEngineConstructorArgs, Options, RestoreFootprintArgs, @@ -283,22 +284,24 @@ export class ContractEngine { * @requires - The wasm file buffer to be set in the contract engine. * * */ - public async uploadWasm(txInvocation: TransactionInvocation): Promise { + public async uploadWasm(args: BaseInvocation): Promise { this.requireWasm() try { const uploadOperation = Operation.uploadContractWasm({ wasm: this.wasm! }) // Wasm verified in requireWasm const result = await this.sorobanTransactionPipeline.execute({ - txInvocation, + txInvocation: args as TransactionInvocation, operations: [uploadOperation], options: { + ...args.options, executionPlugins: [new ExtractWasmHashPlugin()], verboseOutput: true, }, }) this.wasmHash = (result as VerboseExecutedOutput).sorobanGetTransactionPipelineOutput.output?.wasmHash + return result } catch (error) { throw CEError.failedToUploadWasm(error as StellarPlusError) } @@ -312,32 +315,35 @@ export class ContractEngine { * @requires - The wasm hash to be set in the contract engine. * * */ - public async deploy(txInvocation: TransactionInvocation): Promise { + public async deploy(args: BaseInvocation): Promise { this.requireWasmHash() try { const deployOperation = Operation.createCustomContract({ - address: new Address(txInvocation.header.source), + address: new Address(args.header.source), wasmHash: Buffer.from(this.wasmHash!, 'hex'), // Wasm hash verified in requireWasmHash salt: generateRandomSalt(), } as OperationOptions.CreateCustomContract) const result = await this.sorobanTransactionPipeline.execute({ - txInvocation, + txInvocation: args as TransactionInvocation, operations: [deployOperation], options: { + ...args.options, executionPlugins: [new ExtractContractIdPlugin()], verboseOutput: true, }, }) this.contractId = (result as VerboseExecutedOutput).sorobanGetTransactionPipelineOutput.output?.contractId + + return result } catch (error) { throw CEError.failedToDeployContract(error as StellarPlusError) } } - public async wrapAndDeployClassicAsset(args: WrapClassicAssetArgs): Promise { + public async wrapAndDeployClassicAsset(args: WrapClassicAssetArgs): Promise { this.requireNoContractId() try { @@ -351,12 +357,15 @@ export class ContractEngine { txInvocation, operations: [wrapOperation], options: { + ...args.options, executionPlugins: [new ExtractContractIdPlugin()], verboseOutput: true, }, }) this.contractId = (result as VerboseExecutedOutput).sorobanGetTransactionPipelineOutput.output?.contractId + + return result } catch (error) { let isAssetAlreadyWrapped = false try { @@ -377,7 +386,7 @@ export class ContractEngine { } } - public async restoreContractInstance(args: TransactionInvocation): Promise { + public async restoreContractInstance(args: BaseInvocation): Promise { return await this.restore({ keys: [(await this.getContractInstanceLedgerEntry()).key], ...(args as TransactionInvocation), @@ -392,7 +401,7 @@ export class ContractEngine { * * @description - Restores the contract code. */ - public async restoreContractCode(args: TransactionInvocation): Promise { + public async restoreContractCode(args: BaseInvocation): Promise { return await this.restore({ keys: [(await this.getContractCodeLedgerEntry()).key], ...(args as TransactionInvocation), @@ -498,6 +507,7 @@ export class ContractEngine { txInvocation, operations: [restoreFootprintOperation], options: { + ...args.options, executionPlugins: [ new InjectPreprocessParameterPlugin< BuildTransactionPipelineInput, diff --git a/src/stellar-plus/core/contract-engine/index.unit.test.ts b/src/stellar-plus/core/contract-engine/index.unit.test.ts index 110af93..010c9cd 100644 --- a/src/stellar-plus/core/contract-engine/index.unit.test.ts +++ b/src/stellar-plus/core/contract-engine/index.unit.test.ts @@ -191,7 +191,7 @@ describe('ContractEngine', () => { }, }) - await expect(contractEngine.uploadWasm(MOCKED_TX_INVOCATION)).resolves.toBeUndefined() + await expect(contractEngine.uploadWasm(MOCKED_TX_INVOCATION)).resolves.toBeDefined() expect(contractEngine.getWasm()).toEqual(MOCKED_WASM_FILE) }) @@ -216,7 +216,7 @@ describe('ContractEngine', () => { }, }) - await expect(contractEngine.deploy(MOCKED_TX_INVOCATION)).resolves.toBeUndefined() + await expect(contractEngine.deploy(MOCKED_TX_INVOCATION)).resolves.toBeDefined() expect(contractEngine.getContractId()).toEqual(MOCKED_CONTRACT_ID) }) }) @@ -514,7 +514,7 @@ describe('ContractEngine', () => { await expect( contractEngine.wrapAndDeployClassicAsset({ asset: MOCKED_STELLAR_ASSET, ...MOCKED_TX_INVOCATION }) - ).resolves.toBeUndefined() + ).resolves.toBeDefined() expect(contractEngine.getContractId()).toEqual(MOCKED_CONTRACT_ID) }) diff --git a/src/stellar-plus/core/contract-engine/types.ts b/src/stellar-plus/core/contract-engine/types.ts index 6c8399d..a7cb9ac 100644 --- a/src/stellar-plus/core/contract-engine/types.ts +++ b/src/stellar-plus/core/contract-engine/types.ts @@ -23,6 +23,10 @@ export type Options = { sorobanTransactionPipeline?: SorobanTransactionPipelineOptions } +export type BaseInvocation = TransactionInvocation & { + options?: SorobanTransactionPipelineInput['options'] +} + export type TransactionResources = { cpuInstructions?: number ram?: number @@ -48,15 +52,7 @@ export type SorobanSimulateArgs = { options?: SorobanTransactionPipelineInput['options'] } -export type SorobanUploadArgs = TransactionInvocation & { - wasm: Buffer -} - -export type SorobanDeployArgs = TransactionInvocation & { - wasmHash: string -} - -export type WrapClassicAssetArgs = TransactionInvocation & { +export type WrapClassicAssetArgs = BaseInvocation & { asset: StellarAsset } @@ -65,7 +61,7 @@ export type ExtendFootprintTTLArgs = TransactionInvocation & { footprint: xdr.LedgerFootprint } -export type RestoreFootprintArgs = TransactionInvocation & +export type RestoreFootprintArgs = BaseInvocation & (RestoreFootprintWithLedgerKeys | RestoreFootprintWithRestorePreamble) export type RestoreFootprintWithLedgerKeys = {