1import { expect } from "chai";2import usingApi from "./substrate/substrate-api";3import promisifySubstrate from "./substrate/promisify-substrate";4import fs from "fs";5import privateKey from "./substrate/privateKey";6import { compactAddLength, u8aToU8a } from '@polkadot/util';7import { Hash, AccountId } from "@polkadot/types/interfaces";8import { Abi, PromiseContract } from "@polkadot/api-contract";9import { ISubmittableResult } from "@polkadot/types/types";10import BN from "bn.js";11import { alicesPublicKey } from "./accounts";1213describe('Flipper', () => {14 it(`Can deploy smart contract Flipper, instantiate it and call it's get and flip messages.`, async () => {15 await usingApi(async api => {16 const wasm = fs.readFileSync('./src/flipper/flipper.wasm');17 const contract = compactAddLength(u8aToU8a(wasm));1819 const metadata = JSON.parse(fs.readFileSync('./src/flipper/metadata.json').toString('utf-8'));20 const abi = new Abi(api.registry as any, metadata);2122 const alicesPrivateKey = privateKey('//Alice');2324 const contractHash = await promisifySubstrate(api, () => {25 return new Promise<Hash>(async (resolve, reject) => {26 const unsubscribe = api.tx.contracts.putCode(contract).signAndSend(alicesPrivateKey, async result => {27 if(!result.isInBlock){28 return;29 }3031 const record = result.findRecord('contracts', 'CodeStored');3233 if(record) {34 (await unsubscribe)();35 resolve(record.event.data[0] as unknown as Hash);36 } else {37 reject('Failed to find contract hash in putCode transaction result.');38 }39 });40 })41 })();424344 const instanceAccountId = await promisifySubstrate(api, () => {45 return new Promise<AccountId>((resolve, reject) => {46 const args = abi.constructors[0](true);47 const unsubscribe = api.tx.contracts.instantiate(1000000000000000n, 1000000000000n, contractHash, args)48 .signAndSend(alicesPrivateKey, async (result:ISubmittableResult) => {49 if(!result.isInBlock) {50 return;51 }52 const record = result.findRecord('contracts', 'Instantiated');53 if(record) {54 (await unsubscribe)();55 expect(alicesPublicKey).to.be.equal(record.event.data[0].toString());56 resolve(record.event.data[1] as AccountId);57 } else {58 reject('Failed to find instantiated event,');59 }60 });61 });62 })();6364 const contractInstance = new PromiseContract(api, abi, instanceAccountId);65 const getFlipValue = async () => {66 return await promisifySubstrate(api, async () => {67 const result = await contractInstance.call('rpc', 'get', 0, new BN('1000000000000'))68 .send(alicesPublicKey);69 if(!result.isSuccess) {70 throw 'Failed to get flipper value';71 }72 return result.output && result.output.valueOf && result.output.valueOf();73 })();74 }7576 const initialGetResponse = await getFlipValue();77 expect(initialGetResponse).to.be.true;7879 await promisifySubstrate(api, async () => {80 return new Promise<void>(async (resolve, reject) => {81 api.tx.contracts.call(contractInstance.address.toString(), 0, 1000000000000n, contractInstance.getMessage('flip').fn())82 .signAndSend(alicesPrivateKey, async result => {83 if(!result.isInBlock) {84 return;85 }8687 if(result.findRecord('system', 'ExtrinsicSuccess')) {88 resolve();89 }90 else {91 reject('Failed to flip value.');92 }93 })94 });95 })();9697 const afterFlipGetResponse = await getFlipValue();9899 expect(afterFlipGetResponse).to.be.false;100 });101 });102});