From d484696467b6bc3ec0ab01feac3ee4dd2365d7bc Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Thu, 2 Feb 2023 15:41:07 +0900 Subject: [PATCH 01/35] update /quickSign to /quicksign --- packages/libs/client/src/signing/signWithChainweaver.ts | 4 ++-- .../libs/client/src/signing/tests/signWithChainweaver.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/libs/client/src/signing/signWithChainweaver.ts b/packages/libs/client/src/signing/signWithChainweaver.ts index 44bd5641af..322bdf0529 100644 --- a/packages/libs/client/src/signing/signWithChainweaver.ts +++ b/packages/libs/client/src/signing/signWithChainweaver.ts @@ -52,7 +52,7 @@ export async function signWithChainweaver( debug('calling sign api:', body); - const response = await fetch('http://127.0.0.1:9467/v1/quickSign', { + const response = await fetch('http://127.0.0.1:9467/v1/quicksign', { method: 'POST', body, headers: { 'Content-Type': 'application/json;charset=utf-8' }, @@ -84,7 +84,7 @@ export async function signWithChainweaver( } catch (error) { throw new Error( 'An error occurred when adding signatures to the command' + - `\nResponse from v1/quickSign was \`${bodyText}\`. ` + + `\nResponse from v1/quicksign was \`${bodyText}\`. ` + `\nCode: \`${response.status}\`` + `\nText: \`${response.statusText}\` ` + `${error}`, diff --git a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts index e09d2766d6..892b78484f 100644 --- a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts +++ b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts @@ -16,7 +16,7 @@ import fetch from 'cross-fetch'; describe('signWithChainweaver', () => { jest.setTimeout(1000); - it('makes a call on 127.0.0.1:9467/v1/quickSign with transaction', async () => { + it('makes a call on 127.0.0.1:9467/v1/quicksign with transaction', async () => { (fetch as jest.Mock).mockResolvedValue({ status: 200, text: () => JSON.stringify({ results: [] }), @@ -45,7 +45,7 @@ describe('signWithChainweaver', () => { const body = JSON.stringify({ reqs: [{ cmd, hash, sigs }] }); await signWithChainweaver(unsignedCommand); - expect(fetch).toBeCalledWith('http://127.0.0.1:9467/v1/quickSign', { + expect(fetch).toBeCalledWith('http://127.0.0.1:9467/v1/quicksign', { body, headers: { 'Content-Type': 'application/json;charset=utf-8' }, method: 'POST', From 8fadb38d13338e9617bb6c2b627c0e86ff2be249 Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Thu, 2 Feb 2023 15:46:35 +0900 Subject: [PATCH 02/35] rush change --- .../client/fix-update-quicksign_2023-02-02-06-46.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 common/changes/@kadena/client/fix-update-quicksign_2023-02-02-06-46.json diff --git a/common/changes/@kadena/client/fix-update-quicksign_2023-02-02-06-46.json b/common/changes/@kadena/client/fix-update-quicksign_2023-02-02-06-46.json new file mode 100644 index 0000000000..e6d3e43f2f --- /dev/null +++ b/common/changes/@kadena/client/fix-update-quicksign_2023-02-02-06-46.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@kadena/client", + "comment": "update /quickSign to /quicksign in client/signWithChainweaver", + "type": "patch" + } + ], + "packageName": "@kadena/client" +} \ No newline at end of file From eac3f45620f337d72448d47fa8ad052282df0c2b Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Wed, 15 Feb 2023 20:05:46 +0900 Subject: [PATCH 03/35] update requestBody --- packages/libs/client/etc/client.api.md | 18 +++++++++++++++++- .../src/interfaces/IUnsignedTransaction.ts | 17 +++++++++++++++++ .../client/src/signing/signWithChainweaver.ts | 19 ++++++++++--------- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/packages/libs/client/etc/client.api.md b/packages/libs/client/etc/client.api.md index d36fd8a086..4e6f58fab9 100644 --- a/packages/libs/client/etc/client.api.md +++ b/packages/libs/client/etc/client.api.md @@ -28,7 +28,7 @@ export function createPactCommandFromTemplate(tpl: IPactCommand): PactCommand; // @alpha (undocumented) export interface IChainweaverQuickSignRequestBody { // (undocumented) - reqs: IUnsignedTransaction[]; + cmdSigDatas: IUnsignedChainweaverTransaction[]; } // @alpha (undocumented) @@ -125,6 +125,14 @@ export interface IPublicMeta { ttl: number; } +// @alpha (undocumented) +export interface ISigner { + // (undocumented) + pubKey: string; + // (undocumented) + sig: string | undefined; +} + // @alpha (undocumented) export interface ITemplate { // (undocumented) @@ -133,6 +141,14 @@ export interface ITemplate { parts: TemplateParts; } +// @alpha (undocumented) +export interface IUnsignedChainweaverTransaction { + // (undocumented) + cmd: string; + // (undocumented) + sigs: ISigner[]; +} + // @alpha (undocumented) export interface IUnsignedTransaction { // (undocumented) diff --git a/packages/libs/client/src/interfaces/IUnsignedTransaction.ts b/packages/libs/client/src/interfaces/IUnsignedTransaction.ts index d8af2579ff..b738a8edda 100644 --- a/packages/libs/client/src/interfaces/IUnsignedTransaction.ts +++ b/packages/libs/client/src/interfaces/IUnsignedTransaction.ts @@ -1,3 +1,20 @@ +/** + * @alpha + */ +export interface ISigner { + pubKey: string; + sig: string | undefined; +} + +/** + * @alpha + */ +export interface IUnsignedChainweaverTransaction { + // eslint-disable-next-line @rushstack/no-new-null + sigs: ISigner[]; + cmd: string; +} + /** * @alpha */ diff --git a/packages/libs/client/src/signing/signWithChainweaver.ts b/packages/libs/client/src/signing/signWithChainweaver.ts index 322bdf0529..c35007682c 100644 --- a/packages/libs/client/src/signing/signWithChainweaver.ts +++ b/packages/libs/client/src/signing/signWithChainweaver.ts @@ -1,5 +1,5 @@ import { IPactCommand } from '../interfaces/IPactCommand'; -import { IUnsignedTransaction } from '../interfaces/IUnsignedTransaction'; +import { IUnsignedChainweaverTransaction } from '../interfaces/IUnsignedTransaction'; import { ICommandBuilder } from '../pact'; import fetch from 'cross-fetch'; @@ -23,7 +23,7 @@ export interface IChainweaverSignedCommand { * @alpha */ export interface IChainweaverQuickSignRequestBody { - reqs: IUnsignedTransaction[]; + cmdSigDatas: IUnsignedChainweaverTransaction[]; } const debug: Debugger = _debug('pactjs:signWithChainweaver'); @@ -35,22 +35,23 @@ export async function signWithChainweaver( ...transactions: (IPactCommand & ICommandBuilder>)[] ): Promise<(IPactCommand & ICommandBuilder>)[]> { const quickSignRequest: IChainweaverQuickSignRequestBody = { - reqs: transactions.map((t) => { + cmdSigDatas: transactions.map((t) => { const command = t.createCommand(); return { cmd: command.cmd, - hash: command.hash, - sigs: t.signers.reduce((sigsObject, signer, i) => { - const sig = t.sigs[i]?.sig; - sigsObject[signer.pubKey] = sig === undefined ? null : sig; - return sigsObject; - }, {} as Record), + sigs: t.signers.map((signer, i) => { + return { + pubKey: signer.pubKey, + sig: t.sigs[i]?.sig, + }; + }), }; }), }; const body: string = JSON.stringify(quickSignRequest); debug('calling sign api:', body); + console.log(JSON.stringify(quickSignRequest), body); const response = await fetch('http://127.0.0.1:9467/v1/quicksign', { method: 'POST', From ad723e0dbe933740bc0c2e30a0af56be00496fee Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Thu, 16 Feb 2023 17:59:08 +0900 Subject: [PATCH 04/35] add null to ISignature, pubkey => pubKey in addSignatures, update ChainweaverResponse --- packages/libs/client/etc/client.api.md | 35 ++++++++++------ .../src/interfaces/IChainweaverResponse.ts | 20 +++++++++ .../client/src/interfaces/IPactCommand.ts | 2 +- .../src/interfaces/IUnsignedTransaction.ts | 2 +- packages/libs/client/src/pact.ts | 14 ++++--- .../client/src/signing/signWithChainweaver.ts | 41 +++++++------------ .../signing/tests/signWithChainweaver.test.ts | 21 ++++++---- packages/libs/types/etc/types.api.md | 6 +-- packages/libs/types/src/SignCommand.ts | 6 +-- 9 files changed, 88 insertions(+), 59 deletions(-) create mode 100644 packages/libs/client/src/interfaces/IChainweaverResponse.ts diff --git a/packages/libs/client/etc/client.api.md b/packages/libs/client/etc/client.api.md index 4e6f58fab9..d13e84e2d4 100644 --- a/packages/libs/client/etc/client.api.md +++ b/packages/libs/client/etc/client.api.md @@ -31,19 +31,30 @@ export interface IChainweaverQuickSignRequestBody { cmdSigDatas: IUnsignedChainweaverTransaction[]; } -// @alpha (undocumented) -export type IChainweaverSig = string; +// @public (undocumented) +export interface IChainweaverResponse { + // Warning: (ae-incompatible-release-tags) The symbol "commandSigData" is marked as @public, but its signature references "IChainweaverResponseCommand" which is marked as @alpha + // + // (undocumented) + commandSigData: IChainweaverResponseCommand; + // (undocumented) + outcome: { + hash: string; + result: 'success' | 'noSig'; + }; +} // @alpha (undocumented) -export interface IChainweaverSignedCommand { +export interface IChainweaverResponseCommand { // (undocumented) cmd: string; // (undocumented) - sigs: { - [pubkey: string]: IChainweaverSig; - }; + sigs: ISigner[]; } +// @alpha (undocumented) +export type IChainweaverSig = string; + // @alpha (undocumented) export interface ICommandBuilder, TArgs extends Array = TCaps[keyof TCaps]> { // (undocumented) @@ -52,8 +63,8 @@ export interface ICommandBuilder, TArgs exte addData: (data: IPactCommand['data']) => ICommandBuilder & IPactCommand; // (undocumented) addSignatures(...sig: { - pubkey: string; - sig: string; + pubKey: string; + sig: string | null; }[]): ICommandBuilder & IPactCommand; // (undocumented) createCommand(): ICommand; @@ -102,7 +113,7 @@ export interface IPactCommand { }[]; }[]; // (undocumented) - sigs: (ISignature | undefined)[]; + sigs: (ISignature | undefined | null)[]; // (undocumented) type: string; } @@ -130,7 +141,7 @@ export interface ISigner { // (undocumented) pubKey: string; // (undocumented) - sig: string | undefined; + sig: string | null; } // @alpha (undocumented) @@ -179,8 +190,8 @@ export class PactCommand implements IPactCommand, ICommandBuilder; addSignatures( ...sig: { - pubkey: string; - sig: string; + pubKey: string; + sig: string | null; }[] ): ICommandBuilder & IPactCommand; status: string; @@ -214,7 +214,7 @@ export class PactCommand // convert to IUnsignedTransaction const command: ICommand = { hash, - sigs: this.sigs.map((s) => (s === undefined ? { sig: '' } : s)), + sigs: this.sigs.map((s) => (s === undefined ? { sig: null } : s)), cmd, }; @@ -377,10 +377,12 @@ export class PactCommand return poll({ requestKeys: [this.requestKey] }, apiHost); } - public addSignatures(...sigs: { pubkey: string; sig: string }[]): this { - sigs.forEach(({ pubkey, sig }) => { + public addSignatures( + ...sigs: { pubKey: string; sig: string | null }[] + ): this { + sigs.forEach(({ pubKey: key, sig }) => { const foundSignerIndex = this.signers.findIndex( - ({ pubKey }) => pubKey === pubkey, + ({ pubKey }) => pubKey === key, ); if (foundSignerIndex === -1) { throw new Error('Cannot add signature, public key not present'); diff --git a/packages/libs/client/src/signing/signWithChainweaver.ts b/packages/libs/client/src/signing/signWithChainweaver.ts index c35007682c..747136437f 100644 --- a/packages/libs/client/src/signing/signWithChainweaver.ts +++ b/packages/libs/client/src/signing/signWithChainweaver.ts @@ -1,5 +1,12 @@ +import { + IChainweaverResponse, + IChainweaverResponseCommand, +} from '../interfaces/IChainweaverResponse'; import { IPactCommand } from '../interfaces/IPactCommand'; -import { IUnsignedChainweaverTransaction } from '../interfaces/IUnsignedTransaction'; +import { + ISigner, + IUnsignedChainweaverTransaction, +} from '../interfaces/IUnsignedTransaction'; import { ICommandBuilder } from '../pact'; import fetch from 'cross-fetch'; @@ -11,14 +18,6 @@ import _debug from 'debug'; */ export type IChainweaverSig = string; -/** - * @alpha - */ -export interface IChainweaverSignedCommand { - sigs: { [pubkey: string]: IChainweaverSig }; - cmd: string; -} - /** * @alpha */ @@ -42,16 +41,16 @@ export async function signWithChainweaver( sigs: t.signers.map((signer, i) => { return { pubKey: signer.pubKey, - sig: t.sigs[i]?.sig, + sig: t.sigs[i]?.sig || null, }; }), }; }), }; + const body: string = JSON.stringify(quickSignRequest); debug('calling sign api:', body); - console.log(JSON.stringify(quickSignRequest), body); const response = await fetch('http://127.0.0.1:9467/v1/quicksign', { method: 'POST', @@ -64,23 +63,13 @@ export async function signWithChainweaver( // response is not JSON when not-ok, that's why we use try-catch try { const result = JSON.parse(bodyText) as { - results: IChainweaverSignedCommand[]; + responses: IChainweaverResponse[]; }; - result.results.map((signedCommand, i) => { - transactions[i].addSignatures( - ...Object.keys(signedCommand.sigs).reduce( - (sigs, pubkey) => { - const sig = signedCommand.sigs[pubkey]; - sigs.push({ pubkey, sig }); - return sigs; - }, - [] as { - pubkey: string; - sig: string; - }[], - ), - ); + + result.responses.map((signedCommand, i) => { + transactions[i].addSignatures(...signedCommand.commandSigData.sigs); }); + return transactions; } catch (error) { throw new Error( diff --git a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts index 892b78484f..27243628be 100644 --- a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts +++ b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts @@ -7,7 +7,7 @@ jest.mock('cross-fetch', () => { import { IPactCommand } from '../../interfaces/IPactCommand'; import { ICommandBuilder, Pact } from '../../pact'; import { - IChainweaverSignedCommand, + IChainweaverResponseCommand, signWithChainweaver, } from '../signWithChainweaver'; @@ -36,8 +36,7 @@ describe('signWithChainweaver', () => { const { cmd, hash } = unsignedCommand.createCommand(); const sigs = unsignedCommand.sigs.reduce((sigs, sig, i) => { const pubkey = unsignedCommand.signers[i].pubKey; - sigs[pubkey] = - sig === undefined ? null : sig.sig === undefined ? null : sig.sig; + sigs[pubkey] = sig?.sig || null; return sigs; // eslint-disable-next-line @rushstack/no-new-null }, {} as { [pubkey: string]: string | null }); @@ -80,8 +79,13 @@ describe('signWithChainweaver', () => { }); it('adds signatures in multisig fashion to the transactions', async () => { - const mockedResponse: { results: IChainweaverSignedCommand[] } = { - results: [{ cmd: '', sigs: { 'gas-signer-pubkey': 'gas-key-sig' } }], + const mockedResponse: { responses: IChainweaverResponseCommand[] } = { + responses: [ + { + cmd: '', + sigs: [{ pubKey: 'gas-signer-pubkey', sig: 'gas-key-sig' }], + }, + ], }; (fetch as jest.Mock).mockResolvedValue({ status: 200, @@ -106,9 +110,12 @@ describe('signWithChainweaver', () => { expect(unsignedCommand.sigs).toEqual([{ sig: 'gas-key-sig' }, undefined]); // set a new mock response for the second signature - const mockedResponse2: { results: IChainweaverSignedCommand[] } = { + const mockedResponse2: { results: IChainweaverResponseCommand[] } = { results: [ - { cmd: '', sigs: { 'transfer-signer-pubkey': 'transfer-key-sig' } }, + { + cmd: '', + sigs: [{ pubKey: 'transfer-signer-pubkey', sig: 'transfer-key-sig' }], + }, ], }; (fetch as jest.Mock).mockResolvedValue({ diff --git a/packages/libs/types/etc/types.api.md b/packages/libs/types/etc/types.api.md index fcce943d07..7f9c53af48 100644 --- a/packages/libs/types/etc/types.api.md +++ b/packages/libs/types/etc/types.api.md @@ -210,7 +210,7 @@ export interface ISendRequestBody { // @alpha (undocumented) export interface ISignature { // (undocumented) - sig: string | undefined; + sig: string | undefined | null; } // @alpha (undocumented) @@ -230,7 +230,7 @@ export interface ISignedSignatureWithHash extends ISignature { // (undocumented) pubKey: string; // (undocumented) - sig: string | undefined; + sig: string | undefined | null; } // @alpha @@ -270,7 +270,7 @@ export interface IUnsignedSignatureWithHash extends ISignature { // (undocumented) pubKey?: string; // (undocumented) - sig: string | undefined; + sig: string | undefined | null; } // @alpha (undocumented) diff --git a/packages/libs/types/src/SignCommand.ts b/packages/libs/types/src/SignCommand.ts index 5307e305c5..12bfa64b25 100644 --- a/packages/libs/types/src/SignCommand.ts +++ b/packages/libs/types/src/SignCommand.ts @@ -2,7 +2,7 @@ * @alpha */ export interface ISignature { - sig: string | undefined; + sig: string | undefined | null; } /** @@ -10,7 +10,7 @@ export interface ISignature { */ export interface ISignedSignatureWithHash extends ISignature { hash: string; - sig: string | undefined; + sig: string | undefined | null; pubKey: string; } @@ -19,7 +19,7 @@ export interface ISignedSignatureWithHash extends ISignature { */ export interface IUnsignedSignatureWithHash extends ISignature { hash: string; - sig: string | undefined; + sig: string | undefined | null; pubKey?: string; } From 981dafac35a0cf57669ed70edd1a710d4c4a1d5b Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Fri, 17 Feb 2023 01:47:41 +0900 Subject: [PATCH 05/35] fix import and rewrite --- packages/libs/client/etc/client.api.md | 21 ------------------- .../src/interfaces/IChainweaverResponse.ts | 2 +- packages/libs/client/src/pact.ts | 8 ++++--- .../client/src/signing/signWithChainweaver.ts | 5 +---- 4 files changed, 7 insertions(+), 29 deletions(-) diff --git a/packages/libs/client/etc/client.api.md b/packages/libs/client/etc/client.api.md index d13e84e2d4..e6b3f950c0 100644 --- a/packages/libs/client/etc/client.api.md +++ b/packages/libs/client/etc/client.api.md @@ -31,27 +31,6 @@ export interface IChainweaverQuickSignRequestBody { cmdSigDatas: IUnsignedChainweaverTransaction[]; } -// @public (undocumented) -export interface IChainweaverResponse { - // Warning: (ae-incompatible-release-tags) The symbol "commandSigData" is marked as @public, but its signature references "IChainweaverResponseCommand" which is marked as @alpha - // - // (undocumented) - commandSigData: IChainweaverResponseCommand; - // (undocumented) - outcome: { - hash: string; - result: 'success' | 'noSig'; - }; -} - -// @alpha (undocumented) -export interface IChainweaverResponseCommand { - // (undocumented) - cmd: string; - // (undocumented) - sigs: ISigner[]; -} - // @alpha (undocumented) export type IChainweaverSig = string; diff --git a/packages/libs/client/src/interfaces/IChainweaverResponse.ts b/packages/libs/client/src/interfaces/IChainweaverResponse.ts index 8fbac8ba6b..3c6ec416e8 100644 --- a/packages/libs/client/src/interfaces/IChainweaverResponse.ts +++ b/packages/libs/client/src/interfaces/IChainweaverResponse.ts @@ -1,4 +1,4 @@ -import { ISigner } from 'IUnsignedTransaction'; +import { ISigner } from './IUnsignedTransaction'; /** * @alpha diff --git a/packages/libs/client/src/pact.ts b/packages/libs/client/src/pact.ts index 1519c2ba82..2b7c35a9d8 100644 --- a/packages/libs/client/src/pact.ts +++ b/packages/libs/client/src/pact.ts @@ -312,7 +312,9 @@ export class PactCommand interval = 5000, timeout = 1000 * 60 * 3, onPoll = () => {}, - } = { ...options }; + } = { + ...options, + }; const endTime = Date.now() + timeout; this.status = 'pending'; @@ -380,9 +382,9 @@ export class PactCommand public addSignatures( ...sigs: { pubKey: string; sig: string | null }[] ): this { - sigs.forEach(({ pubKey: key, sig }) => { + sigs.forEach(({ pubKey, sig }) => { const foundSignerIndex = this.signers.findIndex( - ({ pubKey }) => pubKey === key, + (signer) => signer.pubKey === pubKey, ); if (foundSignerIndex === -1) { throw new Error('Cannot add signature, public key not present'); diff --git a/packages/libs/client/src/signing/signWithChainweaver.ts b/packages/libs/client/src/signing/signWithChainweaver.ts index 747136437f..92f7907687 100644 --- a/packages/libs/client/src/signing/signWithChainweaver.ts +++ b/packages/libs/client/src/signing/signWithChainweaver.ts @@ -1,7 +1,4 @@ -import { - IChainweaverResponse, - IChainweaverResponseCommand, -} from '../interfaces/IChainweaverResponse'; +import { IChainweaverResponse } from '../interfaces/IChainweaverResponse'; import { IPactCommand } from '../interfaces/IPactCommand'; import { ISigner, From 8b5c60ace92c783dbe7bfdd654f90fd32a95b212 Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Fri, 17 Feb 2023 22:53:47 +0900 Subject: [PATCH 06/35] update signWithChainweaver tests --- .../client/src/signing/signWithChainweaver.ts | 5 +- .../signing/tests/signWithChainweaver.test.ts | 52 ++++++++++++------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/packages/libs/client/src/signing/signWithChainweaver.ts b/packages/libs/client/src/signing/signWithChainweaver.ts index 92f7907687..be70f2a3d5 100644 --- a/packages/libs/client/src/signing/signWithChainweaver.ts +++ b/packages/libs/client/src/signing/signWithChainweaver.ts @@ -1,9 +1,6 @@ import { IChainweaverResponse } from '../interfaces/IChainweaverResponse'; import { IPactCommand } from '../interfaces/IPactCommand'; -import { - ISigner, - IUnsignedChainweaverTransaction, -} from '../interfaces/IUnsignedTransaction'; +import { IUnsignedChainweaverTransaction } from '../interfaces/IUnsignedTransaction'; import { ICommandBuilder } from '../pact'; import fetch from 'cross-fetch'; diff --git a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts index 27243628be..54c09d9a8a 100644 --- a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts +++ b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts @@ -4,12 +4,10 @@ jest.mock('cross-fetch', () => { default: jest.fn(), }; }); +import { IChainweaverResponse } from '../../interfaces/IChainweaverResponse'; import { IPactCommand } from '../../interfaces/IPactCommand'; import { ICommandBuilder, Pact } from '../../pact'; -import { - IChainweaverResponseCommand, - signWithChainweaver, -} from '../signWithChainweaver'; +import { signWithChainweaver } from '../signWithChainweaver'; import fetch from 'cross-fetch'; @@ -19,7 +17,7 @@ describe('signWithChainweaver', () => { it('makes a call on 127.0.0.1:9467/v1/quicksign with transaction', async () => { (fetch as jest.Mock).mockResolvedValue({ status: 200, - text: () => JSON.stringify({ results: [] }), + text: () => JSON.stringify({ responses: [] }), json: () => {}, }); @@ -33,15 +31,15 @@ describe('signWithChainweaver', () => { IPactCommand ).addCap('GAS', 'signer-key'); - const { cmd, hash } = unsignedCommand.createCommand(); - const sigs = unsignedCommand.sigs.reduce((sigs, sig, i) => { - const pubkey = unsignedCommand.signers[i].pubKey; - sigs[pubkey] = sig?.sig || null; - return sigs; - // eslint-disable-next-line @rushstack/no-new-null - }, {} as { [pubkey: string]: string | null }); + const { cmd } = unsignedCommand.createCommand(); + const sigs = unsignedCommand.sigs.map((sig, i) => { + return { + pubKey: unsignedCommand.signers[i].pubKey, + sig: sig || null, + }; + }); - const body = JSON.stringify({ reqs: [{ cmd, hash, sigs }] }); + const body = JSON.stringify({ cmdSigDatas: [{ cmd, sigs }] }); await signWithChainweaver(unsignedCommand); expect(fetch).toBeCalledWith('http://127.0.0.1:9467/v1/quicksign', { @@ -79,11 +77,17 @@ describe('signWithChainweaver', () => { }); it('adds signatures in multisig fashion to the transactions', async () => { - const mockedResponse: { responses: IChainweaverResponseCommand[] } = { + const mockedResponse: { responses: IChainweaverResponse[] } = { responses: [ { - cmd: '', - sigs: [{ pubKey: 'gas-signer-pubkey', sig: 'gas-key-sig' }], + commandSigData: { + cmd: '', + sigs: [{ pubKey: 'gas-signer-pubkey', sig: 'gas-key-sig' }], + }, + outcome: { + hash: '', + result: 'success', + }, }, ], }; @@ -110,11 +114,19 @@ describe('signWithChainweaver', () => { expect(unsignedCommand.sigs).toEqual([{ sig: 'gas-key-sig' }, undefined]); // set a new mock response for the second signature - const mockedResponse2: { results: IChainweaverResponseCommand[] } = { - results: [ + const mockedResponse2: { responses: IChainweaverResponse[] } = { + responses: [ { - cmd: '', - sigs: [{ pubKey: 'transfer-signer-pubkey', sig: 'transfer-key-sig' }], + commandSigData: { + cmd: '', + sigs: [ + { pubKey: 'transfer-signer-pubkey', sig: 'transfer-key-sig' }, + ], + }, + outcome: { + hash: '', + result: 'success', + }, }, ], }; From 202c362b14aafc4058e53ae66e67dff2d017eeb4 Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Fri, 17 Feb 2023 22:56:41 +0900 Subject: [PATCH 07/35] run rush change --- .../client/fix-update-quicksign_2023-02-17-13-56.json | 10 ++++++++++ .../types/fix-update-quicksign_2023-02-17-13-56.json | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 common/changes/@kadena/client/fix-update-quicksign_2023-02-17-13-56.json create mode 100644 common/changes/@kadena/types/fix-update-quicksign_2023-02-17-13-56.json diff --git a/common/changes/@kadena/client/fix-update-quicksign_2023-02-17-13-56.json b/common/changes/@kadena/client/fix-update-quicksign_2023-02-17-13-56.json new file mode 100644 index 0000000000..78f24c1f17 --- /dev/null +++ b/common/changes/@kadena/client/fix-update-quicksign_2023-02-17-13-56.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@kadena/client", + "comment": "Update with KIP 0015 signing api standard", + "type": "patch" + } + ], + "packageName": "@kadena/client" +} \ No newline at end of file diff --git a/common/changes/@kadena/types/fix-update-quicksign_2023-02-17-13-56.json b/common/changes/@kadena/types/fix-update-quicksign_2023-02-17-13-56.json new file mode 100644 index 0000000000..69a4286523 --- /dev/null +++ b/common/changes/@kadena/types/fix-update-quicksign_2023-02-17-13-56.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@kadena/types", + "comment": "add null type to IUnsignedTransaction sig", + "type": "minor" + } + ], + "packageName": "@kadena/types" +} \ No newline at end of file From b6a9ea380bf1ea40fd4d15226c4a60c2d4c274e1 Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Fri, 17 Feb 2023 23:08:47 +0900 Subject: [PATCH 08/35] minor fix --- packages/libs/client/src/pact.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/libs/client/src/pact.ts b/packages/libs/client/src/pact.ts index 2b7c35a9d8..993b481a32 100644 --- a/packages/libs/client/src/pact.ts +++ b/packages/libs/client/src/pact.ts @@ -214,7 +214,7 @@ export class PactCommand // convert to IUnsignedTransaction const command: ICommand = { hash, - sigs: this.sigs.map((s) => (s === undefined ? { sig: null } : s)), + sigs: this.sigs.map((s) => (!s ? { sig: null } : s)), cmd, }; From cfff536c79e926ca305c5d74929ce34f68d83a78 Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Mon, 20 Feb 2023 22:46:35 +0900 Subject: [PATCH 09/35] add failure / noSig cases in Chainweaver Response and Error --- .../src/interfaces/IChainweaverResponse.ts | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/libs/client/src/interfaces/IChainweaverResponse.ts b/packages/libs/client/src/interfaces/IChainweaverResponse.ts index 3c6ec416e8..d97207d826 100644 --- a/packages/libs/client/src/interfaces/IChainweaverResponse.ts +++ b/packages/libs/client/src/interfaces/IChainweaverResponse.ts @@ -5,10 +5,35 @@ import { ISigner } from './IUnsignedTransaction'; */ export interface IChainweaverResponse { commandSigData: IChainweaverResponseCommand; - outcome: { - hash: string; - result: 'success' | 'noSig'; - }; + outcome: + | { + hash: string; + result: 'success'; + } + | { + msg: string; + result: 'failure'; + } + | { + result: 'noSig'; + }; +} + +/** + * @alpha + */ +export interface IChainweaverError { + error: + | { + type: 'reject'; + } + | { + type: 'emptyList'; + } + | { + type: 'other'; + msg: string; + }; } /** From 19849295a3b354928ac641af752a688774d08ab0 Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Tue, 21 Feb 2023 19:09:20 +0900 Subject: [PATCH 10/35] add noSig case to the test --- .../signing/tests/signWithChainweaver.test.ts | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts index 54c09d9a8a..0e89c77271 100644 --- a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts +++ b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts @@ -141,4 +141,37 @@ describe('signWithChainweaver', () => { { sig: 'transfer-key-sig' }, ]); }); + + it('Wallet signs but does not have the signer key and returns sig null', async () => { + const mockedResponse: { responses: IChainweaverResponse[] } = { + responses: [ + { + commandSigData: { + cmd: '', + sigs: [{ pubKey: 'gas-signer-pubkey', sig: null }], + }, + outcome: { result: 'noSig' }, + }, + ], + }; + + (fetch as jest.Mock).mockResolvedValue({ + status: 200, + text: () => JSON.stringify(mockedResponse), + }); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const pactModule = Pact.modules as any; + + const unsignedCommand = ( + pactModule.coin.transfer('k:from') as ICommandBuilder<{ + GAS: []; + }> & + IPactCommand + ).addCap('GAS', 'gas-signer-pubkey'); + + await signWithChainweaver(unsignedCommand); + + expect(unsignedCommand.sigs).toEqual([{ sig: null }]); + }); }); From 377edcd1c4db5b283386360aee632b1d72d750f9 Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Tue, 21 Feb 2023 20:07:19 +0900 Subject: [PATCH 11/35] handle nullable string value --- packages/libs/client/src/signing/signWithChainweaver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/libs/client/src/signing/signWithChainweaver.ts b/packages/libs/client/src/signing/signWithChainweaver.ts index be70f2a3d5..d0c7ec5d33 100644 --- a/packages/libs/client/src/signing/signWithChainweaver.ts +++ b/packages/libs/client/src/signing/signWithChainweaver.ts @@ -35,7 +35,7 @@ export async function signWithChainweaver( sigs: t.signers.map((signer, i) => { return { pubKey: signer.pubKey, - sig: t.sigs[i]?.sig || null, + sig: t.sigs[i]?.sig ?? null, }; }), }; From 63dde22f3c503161059f84ba712e9a9d0906e81d Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Wed, 22 Feb 2023 17:47:02 +0900 Subject: [PATCH 12/35] add eslint-disable to prevent null warning --- packages/libs/client/src/interfaces/IPactCommand.ts | 1 + packages/libs/client/src/interfaces/IUnsignedTransaction.ts | 1 + packages/libs/client/src/pact.ts | 1 + packages/libs/types/src/SignCommand.ts | 1 + 4 files changed, 4 insertions(+) diff --git a/packages/libs/client/src/interfaces/IPactCommand.ts b/packages/libs/client/src/interfaces/IPactCommand.ts index 04e3828fb9..6ff6194fdf 100644 --- a/packages/libs/client/src/interfaces/IPactCommand.ts +++ b/packages/libs/client/src/interfaces/IPactCommand.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ import { ChainId, ChainwebNetworkId, ICap, ISignature } from '@kadena/types'; /** diff --git a/packages/libs/client/src/interfaces/IUnsignedTransaction.ts b/packages/libs/client/src/interfaces/IUnsignedTransaction.ts index 636af073ab..b12ced134e 100644 --- a/packages/libs/client/src/interfaces/IUnsignedTransaction.ts +++ b/packages/libs/client/src/interfaces/IUnsignedTransaction.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ /** * @alpha */ diff --git a/packages/libs/client/src/pact.ts b/packages/libs/client/src/pact.ts index 993b481a32..204f2f25cd 100644 --- a/packages/libs/client/src/pact.ts +++ b/packages/libs/client/src/pact.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ import { ISendResponse, local, poll, send } from '@kadena/chainweb-node-client'; import { hash as blakeHash } from '@kadena/cryptography-utils'; import { createExp } from '@kadena/pactjs'; diff --git a/packages/libs/types/src/SignCommand.ts b/packages/libs/types/src/SignCommand.ts index 12bfa64b25..8dce53ddc5 100644 --- a/packages/libs/types/src/SignCommand.ts +++ b/packages/libs/types/src/SignCommand.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ /** * @alpha */ From b9c5dbbea037db25fe861fb105d1b02e6320079f Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Wed, 22 Feb 2023 18:42:46 +0900 Subject: [PATCH 13/35] add eslint-disable-next-line for no-new-null errors --- packages/libs/client/src/interfaces/IPactCommand.ts | 1 + packages/libs/client/src/interfaces/IUnsignedTransaction.ts | 1 + packages/libs/client/src/pact.ts | 2 ++ packages/libs/types/src/SignCommand.ts | 3 +++ 4 files changed, 7 insertions(+) diff --git a/packages/libs/client/src/interfaces/IPactCommand.ts b/packages/libs/client/src/interfaces/IPactCommand.ts index 04e3828fb9..7d50f00679 100644 --- a/packages/libs/client/src/interfaces/IPactCommand.ts +++ b/packages/libs/client/src/interfaces/IPactCommand.ts @@ -17,6 +17,7 @@ export interface IPactCommand { }[]; }[]; type: string; + // eslint-disable-next-line @rushstack/no-new-null sigs: (ISignature | undefined | null)[]; } diff --git a/packages/libs/client/src/interfaces/IUnsignedTransaction.ts b/packages/libs/client/src/interfaces/IUnsignedTransaction.ts index 636af073ab..ef96b24d6f 100644 --- a/packages/libs/client/src/interfaces/IUnsignedTransaction.ts +++ b/packages/libs/client/src/interfaces/IUnsignedTransaction.ts @@ -3,6 +3,7 @@ */ export interface ISigner { pubKey: string; + // eslint-disable-next-line @rushstack/no-new-null sig: string | null; } diff --git a/packages/libs/client/src/pact.ts b/packages/libs/client/src/pact.ts index 993b481a32..1730c3b84c 100644 --- a/packages/libs/client/src/pact.ts +++ b/packages/libs/client/src/pact.ts @@ -59,6 +59,7 @@ export interface ICommandBuilder< addSignatures( ...sig: { pubKey: string; + // eslint-disable-next-line @rushstack/no-new-null sig: string | null; }[] ): ICommandBuilder & IPactCommand; @@ -380,6 +381,7 @@ export class PactCommand } public addSignatures( + // eslint-disable-next-line @rushstack/no-new-null ...sigs: { pubKey: string; sig: string | null }[] ): this { sigs.forEach(({ pubKey, sig }) => { diff --git a/packages/libs/types/src/SignCommand.ts b/packages/libs/types/src/SignCommand.ts index 12bfa64b25..6e0b2b1ec5 100644 --- a/packages/libs/types/src/SignCommand.ts +++ b/packages/libs/types/src/SignCommand.ts @@ -2,6 +2,7 @@ * @alpha */ export interface ISignature { + // eslint-disable-next-line @rushstack/no-new-null sig: string | undefined | null; } @@ -10,6 +11,7 @@ export interface ISignature { */ export interface ISignedSignatureWithHash extends ISignature { hash: string; + // eslint-disable-next-line @rushstack/no-new-null sig: string | undefined | null; pubKey: string; } @@ -19,6 +21,7 @@ export interface ISignedSignatureWithHash extends ISignature { */ export interface IUnsignedSignatureWithHash extends ISignature { hash: string; + // eslint-disable-next-line @rushstack/no-new-null sig: string | undefined | null; pubKey?: string; } From 48e833b3d829025001c04715bbdf1949f842e43a Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Wed, 22 Feb 2023 18:45:06 +0900 Subject: [PATCH 14/35] remove eslint-disable --- packages/libs/client/src/interfaces/IPactCommand.ts | 1 - packages/libs/client/src/interfaces/IUnsignedTransaction.ts | 1 - packages/libs/client/src/pact.ts | 1 - packages/libs/types/src/SignCommand.ts | 1 - 4 files changed, 4 deletions(-) diff --git a/packages/libs/client/src/interfaces/IPactCommand.ts b/packages/libs/client/src/interfaces/IPactCommand.ts index a86fb0acd4..7d50f00679 100644 --- a/packages/libs/client/src/interfaces/IPactCommand.ts +++ b/packages/libs/client/src/interfaces/IPactCommand.ts @@ -1,4 +1,3 @@ -/* eslint-disable */ import { ChainId, ChainwebNetworkId, ICap, ISignature } from '@kadena/types'; /** diff --git a/packages/libs/client/src/interfaces/IUnsignedTransaction.ts b/packages/libs/client/src/interfaces/IUnsignedTransaction.ts index 448e9259f5..ef96b24d6f 100644 --- a/packages/libs/client/src/interfaces/IUnsignedTransaction.ts +++ b/packages/libs/client/src/interfaces/IUnsignedTransaction.ts @@ -1,4 +1,3 @@ -/* eslint-disable */ /** * @alpha */ diff --git a/packages/libs/client/src/pact.ts b/packages/libs/client/src/pact.ts index 8b5db86729..1730c3b84c 100644 --- a/packages/libs/client/src/pact.ts +++ b/packages/libs/client/src/pact.ts @@ -1,4 +1,3 @@ -/* eslint-disable */ import { ISendResponse, local, poll, send } from '@kadena/chainweb-node-client'; import { hash as blakeHash } from '@kadena/cryptography-utils'; import { createExp } from '@kadena/pactjs'; diff --git a/packages/libs/types/src/SignCommand.ts b/packages/libs/types/src/SignCommand.ts index 14044a7003..6e0b2b1ec5 100644 --- a/packages/libs/types/src/SignCommand.ts +++ b/packages/libs/types/src/SignCommand.ts @@ -1,4 +1,3 @@ -/* eslint-disable */ /** * @alpha */ From dd3f5feb9944f7fe74ffd269bc948680f8246449 Mon Sep 17 00:00:00 2001 From: Albert G <516972+alber70g@users.noreply.github.com> Date: Thu, 23 Feb 2023 15:33:22 +0100 Subject: [PATCH 15/35] wip: define separate types for pact and signing api --- common/config/rush/pnpm-lock.yaml | 31 + common/config/rush/repo-state.json | 2 +- .../openapi/chainweb.json | 5194 +++++++++++++++++ .../chainweb-node-client/openapi/pact.json | 1316 +++++ .../libs/chainweb-node-client/package.json | 7 +- .../chainweb-node-client/src/openapi/pact.ts | 629 ++ packages/libs/client/etc/client.api.md | 105 +- packages/libs/client/src/index.ts | 3 +- .../src/interfaces/IChainweaverResponse.ts | 45 - .../client/src/interfaces/IPactCommand.ts | 12 +- .../src/interfaces/IUnsignedTransaction.ts | 27 - packages/libs/client/src/pact.ts | 10 +- .../libs/client/src/signing-api/README.md | 4 + .../client/src/signing-api/v1/quicksign.ts | 72 + .../v1/sign.ts | 0 .../client/src/signing/signWithChainweaver.ts | 39 +- .../signing/tests/signWithChainweaver.test.ts | 8 +- packages/libs/client/src/tests/pact.test.ts | 2 +- packages/libs/types/src/PactAPI.ts | 2 + packages/libs/types/src/PactCommand.ts | 7 +- packages/libs/types/src/SignCommand.ts | 3 +- 21 files changed, 7396 insertions(+), 122 deletions(-) create mode 100644 packages/libs/chainweb-node-client/openapi/chainweb.json create mode 100644 packages/libs/chainweb-node-client/openapi/pact.json create mode 100644 packages/libs/chainweb-node-client/src/openapi/pact.ts delete mode 100644 packages/libs/client/src/interfaces/IChainweaverResponse.ts delete mode 100644 packages/libs/client/src/interfaces/IUnsignedTransaction.ts create mode 100644 packages/libs/client/src/signing-api/README.md create mode 100644 packages/libs/client/src/signing-api/v1/quicksign.ts rename packages/libs/client/src/{chainweaver-api => signing-api}/v1/sign.ts (100%) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 85fd27da69..ef81eb8805 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -294,6 +294,8 @@ importers: cross-fetch: ~3.1.5 eslint: ^8.15.0 node-fetch: ~2.6.2 + openapi-typescript: ~6.1.0 + openapi-typescript-fetch: ~1.1.3 dependencies: '@kadena/cryptography-utils': link:../cryptography-utils '@kadena/pactjs': link:../pactjs @@ -309,6 +311,8 @@ importers: '@types/heft-jest': 1.0.3 '@types/node': 16.18.7 eslint: 8.29.0 + openapi-typescript: 6.1.0 + openapi-typescript-fetch: 1.1.3 ../../packages/libs/chainwebjs: specifiers: @@ -4916,6 +4920,11 @@ packages: string-width: 4.2.3 dev: true + /ansi-colors/4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + dev: true + /ansi-escapes/4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -9696,6 +9705,23 @@ packages: is-wsl: 2.2.0 dev: false + /openapi-typescript-fetch/1.1.3: + resolution: {integrity: sha512-smLZPck4OkKMNExcw8jMgrMOGgVGx2N/s6DbKL2ftNl77g5HfoGpZGFy79RBzU/EkaO0OZpwBnslfdBfh7ZcWg==} + engines: {node: '>= 12.0.0', npm: '>= 7.0.0'} + dev: true + + /openapi-typescript/6.1.0: + resolution: {integrity: sha512-4G0hQu9zXHESZe4fZouucmA+6J5oKSBNYzG0gPbV9V4aKBNIwfUY86ur/cxyTMzuN9vQuAiMe//q4ZMXgMvGtQ==} + hasBin: true + dependencies: + ansi-colors: 4.1.3 + fast-glob: 3.2.12 + js-yaml: 4.1.0 + supports-color: 9.3.1 + undici: 5.14.0 + yargs-parser: 21.1.1 + dev: true + /optimism/0.16.2: resolution: {integrity: sha512-zWNbgWj+3vLEjZNIh/okkY2EUfX+vB9TJopzIZwT1xxaMqC5hRLLraePod4c5n4He08xuXNH+zhKFFCu390wiQ==} dependencies: @@ -11247,6 +11273,11 @@ packages: dependencies: has-flag: 4.0.0 + /supports-color/9.3.1: + resolution: {integrity: sha512-knBY82pjmnIzK3NifMo3RxEIRD9E0kIzV4BKcyTZ9+9kWgLMxd4PrsTSMoFQUabgRBbF8KOLRDCyKgNV+iK44Q==} + engines: {node: '>=12'} + dev: true + /supports-hyperlinks/2.3.0: resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} engines: {node: '>=8'} diff --git a/common/config/rush/repo-state.json b/common/config/rush/repo-state.json index 62727007ab..cc952cd8fc 100644 --- a/common/config/rush/repo-state.json +++ b/common/config/rush/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "1cf42a5798192b104ea6a24734132332f8a10c2f", + "pnpmShrinkwrapHash": "637bd197d729f25d04f631aaf65f292dd9a4475f", "preferredVersionsHash": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f" } diff --git a/packages/libs/chainweb-node-client/openapi/chainweb.json b/packages/libs/chainweb-node-client/openapi/chainweb.json new file mode 100644 index 0000000000..7a08cd0362 --- /dev/null +++ b/packages/libs/chainweb-node-client/openapi/chainweb.json @@ -0,0 +1,5194 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Kadena Chainweb Node API", + "description": "API of [chainweb-node](https://github.com/kadena-io/chainweb-node)\n\nChainweb is a scalable Proof-Of-Work (PoW) consensus algorithm. It is an\nconservative extension of Bitcoin's Nakamoto consensus that extends\nBitcoin's single chain algorithm to multiple chains. This allows for\nunlimited transaction throughput by horizontally scaling the number of chains.\n\nFeedback and bug reports for the content of this site are welcome. Please\nopen an issue at [this github repository](https://github.com/kadena-io/chainweb-openapi/issues).\n", + "version": "0.0", + "x-logo": { + "url": "https://i.imgur.com/bAZFAGF.png", + "alttext": "Kadena Chainweb Logo" + } + }, + "servers": [ + { + "url": "https://api.chainweb.com/chainweb/{apiVersion}/mainnet01", + "description": "Chainweb mainnet service API. It also serves some endpoints of the P2P API.\n", + "variables": { + "apiVersion": { + "default": "0.0" + } + } + }, + { + "url": "https://api.testnet.chainweb.com/chainweb/{apiVersion}/testnet04", + "description": "Chainweb testnet service API. It also serves some endpoints of the P2P API.\n", + "variables": { + "apiVersion": { + "default": "0.0" + } + } + }, + { + "url": "{schema}://{domain}:{port}/chainweb/{apiVersion}/{chainwebVersion}", + "description": "An generic chainweb-node. It may serve only a subset of the endpoints.\n", + "variables": { + "schema": { + "default": "http", + "enum": [ + "http", + "https" + ] + }, + "domain": { + "default": "api.chainweb.com" + }, + "port": { + "default": "1848" + }, + "chainwebVersion": { + "default": "mainnet01", + "enum": [ + "test-singleton", + "development", + "mainnet01", + "testnet04" + ] + }, + "apiVersion": { + "default": "0.0" + } + } + }, + { + "url": "https://{location}.chainweb.com/chainweb/{apiVersion}/mainnet01", + "description": "Chainweb mainnet P2P bootstrap node. Only P2P API endpoints are served.", + "variables": { + "location": { + "default": "us-e1", + "enum": [ + "us-e1", + "us-e2", + "us-e3", + "us-w1", + "us-w2", + "us-w3", + "fr1", + "fr2", + "fr3", + "jp1", + "jp2", + "jp3" + ] + }, + "apiVersion": { + "default": "0.0" + } + } + }, + { + "url": "https://{location}.testnet.chainweb.com/chainweb/{apiVersion}/testnet04", + "description": "Chainweb testnet P2P bootstrap node. Only P2P API endpoints are served.", + "variables": { + "location": { + "default": "us-e1", + "enum": [ + "us1", + "us2", + "eu1", + "eu2", + "ap1", + "ap2" + ] + }, + "apiVersion": { + "default": "0.0" + } + } + } + ], + "tags": [ + { + "name": "p2p_api", + "x-displayName": "P2P API", + "description": "The P2P API is used for inter-node communication in order to establish block\nchain consensus. Each chainweb-node serves these endpoints via HTTPS on a\nnetwork interface and port that is available directly on the public\ninternet.\n\nAdditionally, endpoints of the P2P API can be made available for other\nclients. For this purpose it is possible to expose the endpoints via reverse\nproxies, load balancers, or authentication frameworks, and similar web\ntechnologies.\n" + }, + { + "name": "service_api", + "x-displayName": "Service API", + "description": "The Service API includes endpoints that expose functionality of\nchainweb-node to clients other than chainweb-nodes, such as mining pools,\nDAPPs, web applications, exchanges, wallets, etc.\n\nThe endpoints of the service API are optional and can be enabled via\nrespective configuration settings. They are served on a separate port via\nplain HTTP. Node operators are free to expose those endpoints only locally,\nor via reverse proxies, load balancers, authentication frameworks, and\nsimilar web technologies.\n\nSome of the endpoints of the service API can require considerable resources\non the server side and administrators should be careful when exposing those\npublicly. Generally, endpoints of the service API are more vulnerable to DOS\nattacks.\n" + }, + { + "name": "cut", + "x-displayName": "Cut Endpoints", + "description": "A cut represents a distributed state of a chainweb. It references one\nblock header for each chain, such that those blocks are pairwise\nconcurrent.\n\nTwo blocks from two different chains are said to be concurrent if either\none of them is an adjacent parent (is a direct dependency) of the other or\nif the blocks do not depend at all on each other.\n" + }, + { + "name": "peer", + "x-displayName": "Peer Endpoints", + "description": "The P2P communication between chainweb-nodes is sharded into several independent\nP2P network. The `cut` network is exchanging consensus state. There is also one\nmempool P2P network for each chain.\n" + }, + { + "name": "mempool", + "x-displayName": "Mempool P2P Endpoints", + "description": "Mempool P2P endpoints for communication between mempools. Endusers are not\nsupposed to use these endpoints directly. Instead, the respective Pact\nendpoints should be used for submitting transactions into the network.\n" + }, + { + "name": "payload", + "x-displayName": "Block Payload Endpoints", + "description": "Raw literal Block Payloads in the form in which they are stored on the chain.\nBy default only the payload data is returned which is sufficient for validating\nthe blockchain Merkle Tree. It is also sufficient as input to Pact for\nexecuting the Pact transactions of the block and recomputing the outputs.\n\nIt is also possible to query the transaction outputs along with the payload data.\n" + }, + { + "name": "blockhash", + "x-displayName": "Block Hashes Endpoints", + "description": "These endpoints return block hashes from the chain database.\n\nGenerally, block hashes are returned in ascending order and include hashes\nfrom orphaned blocks.\n\nFor only querying blocks that are included in the winning branch of the\nchain the `branch` endpoint can be used, which returns blocks in descending\norder starting from the leafs of branches of the block chain.\n" + }, + { + "name": "header", + "x-displayName": "Block Header Endpoints", + "description": "These endpoints return block headers from the chain database.\n\nGenerally, block headers are returned in ascending order and include headers\nof orphaned blocks.\n\nFor only querying blocks that are included in the winning branch of the\nchain the `branch` endpoints can be used, which return blocks in descending\norder starting from the leafs of branches of the block chain.\n\nBlock headers are returned in three different formats specified in the `accept` header of the request:\n* `application/json`, returns block headers in base64Url (without padding)\n encoded binary.\n* `application/json;blockheader-encoding=object`, returns block headers in\n JSON encoding.\n* `application/octet-stream`, when supported by the endpoint, returns block\n headers as binary.\n" + }, + { + "name": "config", + "x-displayName": "Config Endpoint" + }, + { + "name": "misc", + "x-displayName": "Miscellaneous Endpoints" + }, + { + "name": "pact", + "x-displayName": "Pact Endpoints", + "description": "The [Pact](https://pactlang.org) endpoints are documented in the [Pact API\nSpecification](./pact.html).\n\nThe Pact endpoints for chain `{chainId}` use the route prefix\n`/chain/{chainId}/pact/` in addition to the base URL.\n\nFuther details can also be found in [this section of the Pact Language\nReference](https://pact-language.readthedocs.io/en/stable/pact-reference.html#endpoints).\n" + }, + { + "name": "rosetta", + "x-displayName": "Rosetta Endpoints", + "description": "Chainweb node includes an implementation of the\n[Rosetta API](https://www.rosetta-api.org). The API is disabled by default\nand can be enabled in the configuration file of a node.\n\nThe following endpoints are supported, which are documented\nin the [Rosetta Specification](https://www.rosetta-api.org/docs/welcome.html):\n\n* `POST rosetta/account/balance`\n* `POST rosetta/block/transaction`\n* `POST rosetta/block`\n* `POST rosetta/construction/metadata`\n* `POST rosetta/construction/submit`\n* `POST rosetta/mempool/transaction`\n* `POST rosetta/mempool`\n* `POST rosetta/network/list`\n* `POST rosetta/network/options`\n* `POST rosetta/network/status`\n" + }, + { + "name": "mining", + "x-displayName": "Mining Endpoints", + "description": "The Mining API of Chainweb node is disabled by default. It can be enabled\nand configured in the configuration file.\n\n\nThe mining API consists of the following endpoints that\nare described in detail on the\n[Chainweb mining wiki page](https://github.com/kadena-io/chainweb-node/wiki/Mining-API)\n\n* `GET mining/work`\n* `POST mining/solved`\n* `GET mining/updates`\n" + }, + { + "name": "binaryHeader", + "x-displayName": "Block Header Binary Encoding", + "description": "## Binary Format For Chain Graphs of Degree Three\n\ndefined in `Chainweb.BlockHeader`\n\n| Size | Bytes | Value |\n| ---- | ------- | ----------- |\n| 8 | 0-7 | flags |\n| 8 | 8-15 | time |\n| 32 | 16-47 | parent |\n| 110 | 48-157 | adjacents |\n| 32 | 158-189 | target |\n| 32 | 190-221 | payload |\n| 4 | 222-225 | chain |\n| 32 | 226-257 | weight |\n| 8 | 258-265 | height |\n| 4 | 266-269 | version |\n| 8 | 270-277 | epoch start |\n| 8 | 278-285 | nonce |\n| 32 | 286-317 | hash |\n\ntotal: 318 bytes\n\nAdjacent Parents Record (length 3):\n\n| Bytes | Value |\n| ----- | --------- |\n| 0-1 | length |\n| 2-109 | adjacents |\n\ntotal: 110 bytes\n\nAdjacent Parent:\n\n| Bytes | Value |\n| ----- | ----- |\n| 0-3 | chain |\n| 4-35 | hash |\n\ntotal: 36 bytes\n\n## Fields\n\n**POW related values**:\n\nArithmetic operations and comparisons on `parent`, `target`, `weight`, and `hash`\ninterpret the value as unsigned 256 bit integral numbers in little endian encoding.\nAll operations are performed using rational arithmetic of unlimited precision and the final result is rounded.\nPlease consult the code for details of how the result is rounded.\n\n**Time Stamps**:\n\n`time` and `epoch start` are a little endian twoth complement encoded integral numbers that count SI microseconds since POSIX epoch (leap seconds are ignored). These numbers are always positive (highest bit is 0).\n\n**Numbers**:\n\n* `height` is a little endian encoded unsigned integral 64 bit number.\n* `length` is a little endian encoded unsigned integral 16 bit number.\n\n**Version**:\n\n`version` identifies the chainweb version. It is a 32 bit value in little endian encoding.\nValues up to 0x0000FFFF are reserved for production versions (which includes `development` and testnets).\n\n| value | version |\n| ---------- | ----------- |\n| 0x00000005 | mainnet01 |\n| 0x00000001 | development |\n| 0x00000007 | testnet04 |\n\n**Other**:\n\n* `nonce` is any sequence of 8 bytes that is only compared for equality.\n* `chain` is any sequence of 4 bytes that identifies a chain and can be compared for equality.\n* `payload` is any sequence of 32 bytes that is a cryptographic hash of the payload associated with the block and can be compared for equality.\n* `flags` are eight bytes of value 0x0 that are reserved for future use.\n" + }, + { + "name": "binaryWorkHeader", + "x-displayName": "Work Header Binary Encoding", + "description": "The work bytes received from the `/miner/work` endpoint is slightly different than the above header format. These headers do not include the block hash, instead prefixing the header above (without hash) with chain id and hash target bytes.\n\nThe first 36 bytes are informational. Only the bytes from position 36 to the end are subject of the POW hash computation.\n\nThe final 8 bytes are the nonce. The creation time is encoded in bytes 44-52 (see above for details of the encoding). Miners are allowed, but not required, to update the time to reflect the solve time for the block more closely.\nA larger value for the creation time increases the accuracy of difficulty adjustment which is in the interest of miners -- the high difficulty guarantees that the outcome of the race of winning blocks is determined by actual hash power. However, blocks that are predated (i.e. have a creation time that is in the future) are rejected during block header validation. Leaving the time unchanged is a valid choice.\n\nMiners must not change or make any assumptions about the content of the \"reserved\" bytes.\n\nDefined in `Chainweb.Miner.Core`\n\n| Size | Bytes | Work Bytes | Value |\n| ---- | ------- | -----------| ----------- |\n| 4 | 0-3 | NA | chain |\n| 32 | 4-35 | NA | hash-target |\n| | | | |\n| 8 | 36-43 | 0-7 | reserved |\n| 8 | 44-51 | 8-15 | **time** |\n| 298 | 52-313 | 16-277 | reserved |\n| 8 | 314-321 | 278-285 | **nonce** |\n\ntotal: 322 bytes\n\n\nFor arithmetic comparisons the `hash-target` is interpreted as unsigned 256 bit integral number in little endian encoding.\n\n`time` is a little endian twoth complement encoded integral number that counts SI microseconds since POSIX epoch (leap seconds are ignored). The value is always positive (highest bit is 0).\n" + }, + { + "name": "cut_model", + "x-displayName": "Cut Model", + "description": "The `origin` property is required for use with the `PUT /cut` endpoint.\n\n" + }, + { + "name": "payload_model", + "x-displayName": "Payload Model", + "description": "\n" + }, + { + "name": "payloadWithOutputs_model", + "x-displayName": "Payload With Outputs Model", + "description": "\n" + }, + { + "name": "header_model", + "x-displayName": "Block Header Model", + "description": "\n" + }, + { + "name": "peer_model", + "x-displayName": "Peer Info Model", + "description": "\n\n## Compute PeerInfo\n\nGenerally, it is easier to query the peer info of a peer using a GET query for a peer database.\nOtherwise the peer info can be computed as follows.\n\nFor peers that use domain names with valid CA signed SSL certificates the peer id is `null`.\n\nFor peers with self-signed certificates the peer id is the base64Url (without padding) encoded\nSHA256 fingerprint of the certificate. For a chainweb-node `NODE` it can be computed as follows:\n\n```sh\necho |\nopenssl s_client -showcerts -servername ${NODE} -connect ${NODE}:443 2>/dev/null |\nopenssl x509 -fingerprint -noout -sha256 |\nsed 's/://g' |\ntail -c 65 |\nxxd -r -p |\nbase64 |\ntr -d '=' |\ntr '/+' '_-'\n```\n" + }, + { + "name": "nodeInfo_model", + "x-displayName": "Chainweb Node Info Model", + "description": "\n" + }, + { + "name": "page_model", + "x-displayName": "Collection Page Model", + "description": "\n" + }, + { + "name": "minerInfo_model", + "x-displayName": "Miner Info Model", + "description": "\n" + }, + { + "name": "miningUpdateEventStream_model", + "x-displayName": "Mining Update Event Stream Model", + "description": "A server-sent event sources that notifies miners when new mining work\nbecomes available. The stream is terminated by the server in regular\nintervals and it is up to the client to request a new stream.\n\nEach event consists of a single line: `event:New Cut`.\nEvents are separated by empty lines.\n\n\n" + }, + { + "name": "commonResponseHeaders", + "x-displayName": "Response Headers", + "description": "\n## Server Timestamp\n\n`x-server-timestamp`: The time of the clock of the remote node\n\n\n\n## Chainweb Node Version\n\n`x-chainweb-node-version`: The version of the remote chainweb node\n\n\n\n## Client Peer Address\n\n`x-peer-addr`: Host and port of the client as observed by the remote node\n\n\n" + } + ], + "x-tagGroups": [ + { + "name": "chainweb_p2p", + "x-displayName": "Chainweb P2P API", + "tags": [ + "p2p_api", + "cut", + "blockhash", + "header", + "payload", + "mempool", + "peer", + "config" + ] + }, + { + "name": "chainweb_service", + "x-displayName": "Chainweb Service API", + "tags": [ + "service_api", + "misc", + "mining", + "pact", + "rosetta" + ] + }, + { + "name": "Common HTTP Headers", + "tags": [ + "commonResponseHeaders" + ] + }, + { + "name": "Data Models", + "tags": [ + "cut_model", + "header_model", + "payload_model", + "payloadWithOutputs_model", + "peer_model", + "nodeInfo_model", + "page_model", + "minerInfo_model", + "miningUpdateEventStream_model" + ] + }, + { + "name": "Binary Encodings", + "tags": [ + "binaryHeader", + "binaryWorkHeader" + ] + } + ], + "components": { + "schemas": { + "posixTimestamp": { + "title": "POSIX Timestamp", + "type": "integer", + "description": "Seconds since POSIX epoch", + "example": 1619108524, + "minimum": 0 + }, + "posixTimestampMicro": { + "title": "POSIX Timestamp in Microseconds", + "type": "integer", + "description": "Microseconds since POSIX epoch", + "example": 1602382624629329, + "minimum": 0 + }, + "chainwebVersion": { + "title": "Chainweb Version", + "description": "The version of the Chainweb network", + "enum": [ + "test-singleton", + "development", + "mainnet01", + "testnet04" + ] + }, + "chainId": { + "title": "Chain ID", + "description": "A Chainweb chain ID. In Kadena Chainweb chains are named by numbers\nstarting form 0. Valid values depend on the current graph at the\nrespective block height of the chainweb version.\n", + "type": "integer", + "minimum": 0, + "example": 0 + }, + "hostAddress": { + "title": "Host Address", + "description": "Host address containing IPv4 and port", + "type": "string", + "pattern": "^\\d{4}.\\d{4}.\\d{4}.\\d{4}:\\d+$", + "example": "10.36.1.3:42988" + }, + "signedTxText": { + "title": "Signed Transaction Text", + "type": "string", + "description": "Text of a JSON encoded signed Pact transaction", + "example": { + "value": { + "hash": "y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw", + "sigs": [ + { + "sig": "8ddc06b37c496f2cadc4f7412405a80faf3ab07482ff5553b9b5fcc73d1b4121275ad5948d9b4078e553b71f8b42eaf6b24135bf2fb4d5840c16bcdde0e35e0f" + } + ], + "cmd": "{\"networkId\":\"mainnet01\",\"payload\":{\"exec\":{\"data\":{\"account-keyset\":{\"pred\":\"keys-all\",\"keys\":[\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\"]}},\"code\":\"(coin.transfer-create \\\"60241f51ea34e05c61fbea9d\\\" \\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\" (read-keyset \\\"account-keyset\\\") 5007.0000)\"}},\"signers\":[{\"pubKey\":\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\",\"clist\":[{\"args\":[\"60241f51ea34e05c61fbea9d\",\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\",5007],\"name\":\"coin.TRANSFER\"},{\"args\":[],\"name\":\"coin.GAS\"}]}],\"meta\":{\"creationTime\":1618949714,\"ttl\":300,\"gasLimit\":600,\"chainId\":\"0\",\"gasPrice\":1.0e-7,\"sender\":\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\"},\"nonce\":\"\\\"2021-04-20T20:16:13.645Z\\\"\"}" + } + } + }, + "requestKey": { + "title": "Request Key", + "type": "string", + "description": "Base64Url-encoded, request key of a Pact transaction", + "pattern": "^[a-zA-Z0-9_-]{43}$", + "minLength": 43, + "maxLength": 43, + "example": "y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw" + }, + "sha256Hash": { + "title": "SHA256 Hash", + "type": "string", + "description": "Base64Url (without padding) encoded SHA256 hash", + "pattern": "^[a-zA-Z0-9_-]{43}$", + "minLength": 43, + "maxLength": 43, + "example": "y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw" + }, + "blockHash": { + "title": "Block Hash", + "description": "Base64Url (without padding) encoded block hash", + "example": "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH7", + "allOf": [ + { + "$ref": "#/components/schemas/sha256Hash" + } + ] + }, + "payloadHash": { + "title": "Block Payload Hash", + "description": "Base64Url (without padding) encoded block payload hash", + "example": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA", + "allOf": [ + { + "$ref": "#/components/schemas/sha256Hash" + } + ] + }, + "blockHeight": { + "title": "Block Height", + "description": "The height of a block is the number of its predecessors in the block chain\n", + "type": "integer", + "minimum": 0, + "example": 1000000 + }, + "blockWeight": { + "title": "Block Weight", + "description": "The POW weight of a block is the sum of the difficulties of the block\nand of all of its ancestors. The difficulty of a block is the maximum\ndifficulty divided by the target.\n\nIt represented as the base64Url (without padding) 256 bit little endian\nencoding of the numerical value.\n", + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{43}$", + "minLength": 43, + "maxLength": 43, + "example": "iil_D0t2MGqjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + }, + "target": { + "title": "PoW Target", + "description": "The PoW target of a block represented as the base64Url (without\npadding) 256 bit little endian encoding of the numerical value.\n", + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{43}$", + "minLength": 43, + "maxLength": 43, + "example": "2uMCnB4lWsErj9w1C1vAp1sHYd-sABf3kgcAAAAAAAA" + }, + "nonce": { + "title": "PoW Nonce", + "description": "PoW nonce of the block. This is computed by the miner such that the\nblock hash is smaller than the target.\n", + "type": "string", + "pattern": "[0-9]+", + "minLength": 1 + }, + "base64Header": { + "title": "Base64Url Block Header", + "description": "Base64Url (without padding) encoded binary block header", + "type": "string", + "pattern": "[a-zA-Z0-9_-]+", + "example": { + "value": { + "$ref": "#/components/examples/base64HeaderPage/value/items/0" + } + } + }, + "backupStatus": { + "title": "Backup job status", + "type": "string", + "pattern": "backup-done|backup-in-progress|backup-failed" + }, + "backupId": { + "title": "Backup job identifier", + "description": "Textual backup job identifier", + "type": "string", + "pattern": "[a-zA-Z0-9_-]+", + "example": 1648665437000 + }, + "binaryHeader": { + "title": "Binary Block Header", + "description": "Binary representation of a block header", + "type": "string", + "minLength": 318, + "maxLength": 318 + }, + "blockHeader": { + "title": "Block Header", + "description": "JSON Encoded Block Header", + "required": [ + "creationTime", + "parent", + "height", + "hash", + "chainId", + "weight", + "featureFlags", + "epochStart", + "adjacents", + "payloadHash", + "chainwebVersion", + "target", + "nonce" + ], + "example": { + "value": { + "$ref": "#/components/examples/blockHeaderPage/value/items/0" + } + }, + "properties": { + "creationTime": { + "$ref": "#/components/schemas/posixTimestampMicro" + }, + "parent": { + "$ref": "#/components/schemas/blockHash" + }, + "height": { + "$ref": "#/components/schemas/blockHeight" + }, + "hash": { + "$ref": "#/components/schemas/blockHash" + }, + "chainId": { + "$ref": "#/components/schemas/chainId" + }, + "weight": { + "$ref": "#/components/schemas/blockWeight" + }, + "featureFlags": { + "type": "integer", + "description": "A reserved value that must be 0." + }, + "epochStart": { + "$ref": "#/components/schemas/posixTimestampMicro" + }, + "adjacents": { + "description": "The block hashes of the adjacent parents of the block. This is\nrepresented as an associative array that maps the adjancent chain\nids to the respective block hash.\n", + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/blockHash" + } + }, + "payloadHash": { + "$ref": "#/components/schemas/payloadHash" + }, + "chainwebVersion": { + "$ref": "#/components/schemas/chainwebVersion" + }, + "target": { + "$ref": "#/components/schemas/target" + }, + "nonce": { + "$ref": "#/components/schemas/nonce" + } + } + }, + "payload": { + "title": "Block Payload", + "description": "Payload of a Block including the Merkle roots for transactions and\ntransaction outputs.\n", + "required": [ + "transactions", + "minerData", + "transactionsHash", + "outputsHash", + "payloadHash" + ], + "example": { + "value": { + "$ref": "#/components/examples/payloads/value/1" + } + }, + "properties": { + "transactions": { + "type": "array", + "description": "Array of base64Url (without padding) encoded JSON texts of signed Pact transactions", + "items": { + "type": "string", + "pattern": "[a-zA-Z0-9_-]+", + "description": "Base64Url (without padding) encoded JSON text of a signed Pact transaction" + } + }, + "minerData": { + "type": "string", + "pattern": "[a-zA-Z0-9_-]+", + "description": "Base64Url (without padding) encoded JSON text of the miner data of the payload" + }, + "transactionsHash": { + "$ref": "#/components/schemas/sha256Hash" + }, + "outputsHash": { + "$ref": "#/components/schemas/sha256Hash" + }, + "payloadHash": { + "$ref": "#/components/schemas/payloadHash" + } + } + }, + "payloadWithOutputs": { + "title": "Block Payload With Outputs", + "description": "Payload with outputs of a Block including the Merkle roots for\ntransactions and transaction outputs\n", + "required": [ + "transactions", + "minerData", + "transactionsHash", + "outputsHash", + "payloadHash", + "coinbase" + ], + "example": { + "value": { + "transactions": [], + "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + "transactionsHash": "nT0j4xw2woMkdXXaopdurXIn24OG-jNMqQzUGfxV_MA", + "outputsHash": "4pXRrZ2K0_V0iGAxQCKrKdLjQTBZHBOQS7P-47kdnhY", + "payloadHash": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA", + "coinbase": "eyJnYXMiOjAsInJlc3VsdCI6eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6IldyaXRlIHN1Y2NlZWRlZCJ9LCJyZXFLZXkiOiJJa2hoV0VGQ2NURlFTMU5MYkdodVkwcHJNRjlOZERjMVgyeE1OMDVUTTNkSk5qSTNVV1pZV2w4NE5Xc2kiLCJsb2dzIjoiZ3Noak1kWFJrVGxKYmIxalZkQWJ6SVVDcGpQb1JBQ2pEbExzRzBXNkJEMCIsIm1ldGFEYXRhIjpudWxsLCJjb250aW51YXRpb24iOm51bGwsInR4SWQiOjEyNzIzNTB9" + } + }, + "properties": { + "transactions": { + "type": "array", + "description": "Array of pairs of transactions and their outputs.\nSigned Pact transactions and outputs are base64Url-encoded without padding.\n", + "items": { + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": { + "anyOf": [ + { + "type": "string", + "pattern": "[a-zA-Z0-9_-]+", + "description": "Base64Url (without padding) encoded JSON text of a signed Pact transaction" + }, + { + "type": "string", + "pattern": "[a-zA-Z0-9_-]+", + "description": "Base64Url (without padding) encoded JSON text of a transaction output" + } + ] + } + } + }, + "minerData": { + "type": "string", + "pattern": "[a-zA-Z0-9_-]+", + "description": "Base64Url (without padding) encoded JSON text of the miner data of the payload" + }, + "transactionsHash": { + "$ref": "#/components/schemas/sha256Hash" + }, + "outputsHash": { + "$ref": "#/components/schemas/sha256Hash" + }, + "payloadHash": { + "$ref": "#/components/schemas/payloadHash" + }, + "coinbase": { + "type": "string", + "pattern": "[a-zA-Z0-9_-]+", + "description": "Base64Url (without padding) encoded JSON text of coinbase output of the block" + } + } + }, + "peer": { + "title": "Peer", + "description": "Peer info object", + "required": [ + "id", + "address" + ], + "example": { + "address": { + "hostname": "85.238.99.91", + "port": 30004 + }, + "id": "PRLmVUcc9AH3fyfMYiWeC4nV2i1iHwc0-aM7iAO8h18" + }, + "properties": { + "id": { + "description": "The base64Url (without padding) encoded SHA256 fingerprint of the\nSSL certificate of the node. This can be null only if the node uses\nan official CA signed certificate\n", + "type": "string", + "nullable": true, + "pattern": "[a-zA-Z0-9_-]{43}" + }, + "address": { + "required": [ + "hostname", + "port" + ], + "properties": { + "hostname": { + "description": "A domain name or IP address. This must be a domain name only if\nthe respective node is using a valid CA signed SSL certificate.\n", + "type": "string", + "oneOf": [ + { + "format": "hostname" + }, + { + "format": "ipv4" + }, + { + "format": "ipv6" + } + ] + }, + "port": { + "description": "Port number", + "type": "integer", + "minimum": 1, + "maximum": 65535 + } + } + } + } + }, + "cut": { + "title": "Cut", + "description": "Cut datastruction of the chainweb API", + "required": [ + "height", + "weight", + "hashes" + ], + "example": { + "value": { + "origin": null, + "height": 30798466, + "weight": "b0wYplmNiTBXCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "hashes": { + "0": { + "height": 1539923, + "hash": "qEaSmWt_tDcJC9AGbgWY9x12LW5VED7hGgfyz9x_S3w" + }, + "1": { + "height": 1539923, + "hash": "TJuC6nfhamfD517gspAZmqD9umR71nAgttDOi1JbBHw" + }, + "2": { + "height": 1539924, + "hash": "4ineCWfnO1rneWuBMLPzqTl2HF_sZpypT_3TEzf3VLc" + }, + "3": { + "height": 1539924, + "hash": "ZEOMXB2ByqzL2HfYVKIZKAnoe4wIeJ2SaltnXDir59k" + }, + "4": { + "height": 1539923, + "hash": "0g0rOoSznVW2BJDBmK0Lbxz22F-sxTZUNIrUs_Q8Ye4" + }, + "5": { + "height": 1539923, + "hash": "5y_TL-clnF_wELMBKyJk0Sz8RVShw_bGQETJdrMkADA" + }, + "6": { + "height": 1539923, + "hash": "YkQKv6P4_C4jRM3RqKK9FWPxIneeLzlkKQS9ATAQYRk" + }, + "7": { + "height": 1539923, + "hash": "j_hJ9iiH_ATyeQeeRN3auGXjbBWiFgnTU0dYPIz8cKM" + }, + "8": { + "height": 1539924, + "hash": "s7c3B55VbDsS6EJ-nc9S5k2kNbPOBGI8xxF3vUg4d4Q" + }, + "9": { + "height": 1539922, + "hash": "bowQf63xSY9owHKhK1yGee2Q0Fn8yL_oCLaEUn-CGoA" + }, + "10": { + "height": 1539924, + "hash": "uP-pHW4QKrV9fN1mlDGwKuaiIDlJW7xYSj1nW53EHM4" + }, + "11": { + "height": 1539924, + "hash": "TIhegjZ0GEC73T4m0BVuFtfLNGuS56IUWEuf93AJ5UU" + }, + "12": { + "height": 1539923, + "hash": "-j1qcAS9Fs-WQmc3WEhzZ96VojxnlIA2TFpfyIv31Zs" + }, + "13": { + "height": 1539923, + "hash": "S-4TqMgWGlK1k33XRlU9w0Lfwr0RvkO5Jn78Au1OglM" + }, + "14": { + "height": 1539923, + "hash": "xSuULf--S4TrgYNz82deaGhnPLWrg3pXkynGeUPUGwA" + }, + "15": { + "height": 1539923, + "hash": "jsc9rugvcHXDiBAuoO9_j8R_b_jchtJJ8b5596i8wVg" + }, + "16": { + "height": 1539923, + "hash": "qs1aEY8kSxfUBb_JRVswv5dYINRXBjGJteC-6RC1hjc" + }, + "17": { + "height": 1539924, + "hash": "xzVBXaQxzlUfUrakDgppUubQBRXGh-Uy0HBdMNwCq_Y" + }, + "18": { + "height": 1539924, + "hash": "4VOHPAqwioySYRycdl5MxfscQHwtlwwCAt7AySYQT98" + }, + "19": { + "height": 1539923, + "hash": "1PrRg20XyQ_2cfgGOgNK9K-cqIJ1vO8-A-RJlfN5m00" + } + }, + "id": "BBz7KeurYTeQ0hMGbwUbQC84cRbVcacoDQTye-3qkXI", + "instance": "mainnet01" + } + }, + "properties": { + "origin": { + "$ref": "#/components/schemas/peer" + }, + "height": { + "description": "The cut height is the sum of the height of all blocks of the cut.\nUsage of this value should be avoided, because its semantics may\nchange in the future\n", + "type": "integer", + "minimum": 0 + }, + "weight": { + "description": "The sum of the weights of all blocks in the cut", + "type": "string", + "pattern": "[a-zA-Z0-9_-]{43}" + }, + "hashes": { + "type": "object", + "required": [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10" + ], + "description": "An object that maps chain Ids to their respective block hash and\nblock height\n", + "additionalProperties": { + "$ref": "#/components/schemas/hashWithBlockHeight" + } + }, + "instance": { + "type": "string" + }, + "id": { + "type": "string" + } + } + }, + "hashWithBlockHeight": { + "title": "Hash with block height", + "description": "A block hash and the height of that block", + "required": [ + "hash", + "height" + ], + "example": { + "height": 1539924, + "hash": "uP-pHW4QKrV9fN1mlDGwKuaiIDlJW7xYSj1nW53EHM4" + }, + "type": "object", + "properties": { + "hash": { + "type": "string", + "pattern": "[a-zA-Z0-9_-]{43}" + }, + "height": { + "type": "integer", + "minimum": 0 + } + } + }, + "nodeInfo": { + "title": "Chainweb Node Info", + "description": "General information about a chainweb node", + "required": [ + "nodeNumberOfChains", + "nodeApiVersion", + "nodeChains", + "nodeVersion", + "nodeGraphHistory" + ], + "example": { + "value": { + "nodeNumberOfChains": 20, + "nodeApiVersion": "0.0", + "nodeChains": [ + "12", + "13", + "14", + "15", + "8", + "9", + "10", + "11", + "4", + "5", + "6", + "7", + "0", + "16", + "1", + "17", + "2", + "18", + "3", + "19" + ], + "nodeVersion": "mainnet01", + "nodeGraphHistory": [ + [ + 0, + [ + [ + 0, + [ + 5, + 2, + 3 + ] + ], + [ + 1, + [ + 4, + 6, + 3 + ] + ], + [ + 2, + [ + 4, + 7, + 0 + ] + ], + [ + 3, + [ + 8, + 0, + 1 + ] + ], + [ + 4, + [ + 9, + 1, + 2 + ] + ], + [ + 5, + [ + 9, + 6, + 0 + ] + ], + [ + 6, + [ + 5, + 7, + 1 + ] + ], + [ + 7, + [ + 8, + 6, + 2 + ] + ], + [ + 8, + [ + 9, + 7, + 3 + ] + ], + [ + 9, + [ + 8, + 4, + 5 + ] + ] + ] + ], + [ + 852054, + [ + [ + 0, + [ + 15, + 10, + 5 + ] + ], + [ + 1, + [ + 11, + 6, + 16 + ] + ], + [ + 2, + [ + 12, + 7, + 17 + ] + ], + [ + 3, + [ + 13, + 8, + 18 + ] + ], + [ + 4, + [ + 14, + 9, + 19 + ] + ], + [ + 5, + [ + 8, + 7, + 0 + ] + ], + [ + 6, + [ + 8, + 9, + 1 + ] + ], + [ + 7, + [ + 9, + 5, + 2 + ] + ], + [ + 8, + [ + 5, + 6, + 3 + ] + ], + [ + 9, + [ + 4, + 6, + 7 + ] + ], + [ + 10, + [ + 11, + 0, + 19 + ] + ], + [ + 11, + [ + 12, + 10, + 1 + ] + ], + [ + 12, + [ + 13, + 11, + 2 + ] + ], + [ + 13, + [ + 12, + 14, + 3 + ] + ], + [ + 14, + [ + 13, + 15, + 4 + ] + ], + [ + 15, + [ + 14, + 0, + 16 + ] + ], + [ + 16, + [ + 15, + 1, + 17 + ] + ], + [ + 17, + [ + 16, + 2, + 18 + ] + ], + [ + 18, + [ + 17, + 3, + 19 + ] + ], + [ + 19, + [ + 10, + 4, + 18 + ] + ] + ] + ] + ] + } + }, + "properties": { + "nodeNumberOfChains": { + "type": "integer", + "minimum": 10, + "example": 20 + }, + "nodeApiVersion": { + "type": "string", + "example": "0.0" + }, + "nodeChains": { + "type": "array", + "items": { + "description": "Chain identifiers", + "type": "string" + }, + "minItems": 0, + "example": [ + "0" + ] + }, + "nodeVersion": { + "type": "string", + "enum": [ + "test-singleton", + "development", + "mainnet01", + "testnet04" + ], + "example": "mainnet01" + }, + "nodeGraphHistory": { + "description": "Array of all chain graphs indexed by the height of the first block with the repective\ngraph. Graphs are encoded as adjacency lists.\n", + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { + "description": "A pair consisting of the height of the first block of a chain graph and the adjacency list of the graph.", + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": { + "oneOf": [ + { + "description": "height of the first block of the graph", + "type": "integer", + "minimum": 0 + }, + { + "description": "adjacency list encoding of the chain graph.", + "type": "array", + "items": { + "description": "A pair of the chain identifier and the list of chains adjacent to it.", + "minItems": 2, + "maxItems": 2, + "type": "array", + "items": { + "oneOf": [ + { + "description": "a chain identifier", + "type": "integer", + "minimum": 0 + }, + { + "description": "an adjacency list for that chain", + "type": "array", + "minItems": 0, + "items": { + "type": "integer", + "minimum": 0 + } + } + ] + } + } + } + ] + } + } + } + } + }, + "page": { + "title": "Page", + "description": "Page of a collection of items", + "required": [ + "next", + "limit", + "items" + ], + "example": { + "value": { + "next": "inclusive:o1S4NNFhKWg8T1HEkmDvsTH9Ut9l3_qHRpp00yRKZIk", + "items": [ + "AAAAAAAAAABRoiLHW7EFAB2lwAatTykipYZ3CZNPzLe-f5S-zUt8COtu0H12f_OZAwAFAAAAMpic85rur2MYf3zli8s8bHxTFjriFoMPTr6ZPs8sjxMKAAAAVBKuhU_hQmuvKlx88A5o-FH0rzNo59NsdxmOGNBQ-ycPAAAAMItdqgHZxf7j6l0oE8X-G9-VyMbnQmZrtSniuRe_EJ9CtyxsSb7daPIIYAaXMgSEsQ3dkxY5GjJjLwAAAAAAABqWlmx5B6wo0YWPIShNKmdVrAQWht2P85BS1drGLpkAAAAAADUJ-ARn7blgHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEIPAAAAAAAFAAAA-na5gFuxBQAFL-3CY4YuAJNGp9KhDkbrKkIPWYyq8WvtAaNPoUFWC16louSx8YN5", + "AAAAAAAAAAA0slHKW7EFAJNGp9KhDkbrKkIPWYyq8WvtAaNPoUFWC16louSx8YN5AwAFAAAAALcxv1ZiwwQ_QX9eOBZMbzIop6n7XtveS1FqOFwyvGMKAAAAC76ElC60qXSJQCHePpzzJxsCYvvrqvmkoHPyZnex-4QPAAAAKv0sz_rTANjoiJwMrdZFCJNFwdH0U_M5ouwMr3BXBfpCtyxsSb7daPIIYAaXMgSEsQ3dkxY5GjJjLwAAAAAAALJlIg1vY3w_9L63bePn1yk_5agvdEbIBBjm3adxc5xWAAAAAGzpBzdiVL9gHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQUIPAAAAAAAFAAAA-na5gFuxBQALiBhXgqaHAb4VWug3oddEVy0X9y_jEkE2Kmi_vyGP5ovr-fDIz_Uf" + ], + "limit": 2 + } + }, + "properties": { + "limit": { + "description": "The number of items in the page. This number can be smaller but\nnever be larger than the number of requested items.\n", + "type": "integer", + "minimum": 0, + "items": { + "description": "Items of the returned collection", + "type": "array" + } + }, + "next": { + "description": "A cursor that can be used to query the next page. It should be used\nliterally as value for the `next` parameter in a follow-up request.\n", + "oneOf": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "nullable": true, + "pattern": "^(inclusive|exclusive):.*$" + }, + "items": { + "description": "The items in the page.\n" + } + } + }, + "miningUpdateEventStream": { + "title": "Mining Update Events", + "description": "A stream of server-sent events. **This is not an JSON array**.\nEvents are separated by empty lines (`\\n\\n`). Each event\nconsists of a single line:\n\n event:New Cut\n", + "type": "array", + "items": { + "title": "New Cut Event", + "description": "A `New Cut` event. **This is not an JSON object**.\nEach event consists of a single `event` propert.\n", + "properties": { + "event": { + "type": "string", + "enum": [ + "New Cut" + ] + } + } + }, + "example": "event:New Cut\n\nevent:New Cut\n\nevent:New Cut" + }, + "minerInfo": { + "title": "Miner Info", + "properties": { + "account": { + "title": "Account Name", + "description": "Miner account name. Usually this is the same as the public key.", + "type": "string", + "example": "f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27" + }, + "predicate": { + "title": "Key Predicate", + "enum": [ + "keys-all", + "keys-any" + ], + "example": "keys-all", + "description": "key predicate. For a single key this is usually `keys-all`." + }, + "public-keys": { + "type": "array", + "items": { + "title": "Miner Public Key", + "type": "string", + "example": "f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27" + } + } + }, + "example": { + "account": "miner", + "predicate": "keys-all", + "public-keys": [ + "f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27" + ] + } + }, + "nodeConfig": { + "title": "Node Configuration", + "description": "The configuration of a node. Private information regarding certificates\nand local networks are removed. The schema is subject to change and not\npart of the stable API.\n", + "example": { + "value": { + "allowReadsInLocal": false, + "rosetta": true, + "throttling": { + "local": 1, + "mining": 2, + "global": 200, + "putPeer": 21 + }, + "serviceApi": { + "interface": "invalid", + "port": 0 + }, + "validateHashesOnReplay": false, + "chainwebVersion": "mainnet01", + "pactQueueSize": 2000, + "mining": { + "coordination": { + "enabled": false, + "updateStreamTimeout": 240, + "limit": 1200, + "updateStreamLimit": 2000, + "miners": [] + }, + "nodeMining": { + "miner": { + "account": "", + "predicate": "keys-all", + "public-keys": [] + }, + "enabled": false + } + }, + "p2p": { + "peer": { + "certificateChainFile": null, + "key": null, + "interface": "*", + "certificateChain": null, + "hostaddress": { + "hostname": "34.70.108.163", + "port": 1789 + }, + "keyFile": null + }, + "maxPeerCount": 100, + "private": false, + "ignoreBootstrapNodes": false, + "maxSessionCount": 8, + "bootstrapReachability": 0.5, + "sessionTimeout": 300, + "peers": [ + { + "address": { + "hostname": "us-e1.chainweb.com", + "port": 443 + }, + "id": null + }, + { + "address": { + "hostname": "us-w1.chainweb.com", + "port": 443 + }, + "id": null + } + ] + }, + "transactionIndex": { + "enabled": true, + "configuration": {} + }, + "gasLimitOfBlock": 150000, + "reorgLimit": 480, + "headerStream": true, + "mempoolP2p": { + "enabled": true, + "configuration": { + "pollInterval": 30, + "maxSessionCount": 6, + "sessionTimeout": 240 + } + }, + "reintroTxs": true, + "cuts": { + "pruneChainDatabase": "none", + "fetchTimeout": 3000000, + "initialCutHeightLimit": null + } + } + } + } + }, + "responses": {}, + "parameters": { + "limit": { + "name": "limit", + "in": "query", + "description": "Maximum number of records that may be returned. The actual number may be\nlower.\n", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + } + }, + "next": { + "name": "next", + "in": "query", + "description": "The cursor for the next page. This value can be found as value of the\n`next` property of the previous page.\n", + "required": false, + "schema": { + "type": "string" + } + }, + "chain": { + "name": "chain", + "in": "path", + "description": "the id of the chain to which the request is sent", + "required": true, + "schema": { + "type": "integer", + "minimum": 0, + "example": 0 + } + }, + "backupId": { + "name": "backupId", + "in": "path", + "description": "The identifier of the backup being checked", + "required": true, + "schema": { + "$ref": "#/components/schemas/backupId" + } + }, + "backupPact": { + "name": "backupPact", + "in": "query", + "description": "Flag, if present back up the Pact databases too. Extra disk space and time required\n", + "required": false, + "allowEmptyValue": true + }, + "minheight": { + "name": "minheight", + "in": "query", + "description": "Minimum block height of the returned headers", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + }, + "example": 500000 + }, + "maxheight": { + "name": "maxheight", + "in": "query", + "description": "Maximum block height of the returned headers", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + }, + "example": 500000 + }, + "payloadHash": { + "name": "payloadHash", + "in": "path", + "required": true, + "description": "Payload hash of a block", + "schema": { + "$ref": "#/components/schemas/payloadHash" + }, + "example": { + "value": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA" + } + }, + "blockHash": { + "name": "blockHash", + "in": "path", + "description": "Block hash of a block", + "required": true, + "schema": { + "$ref": "#/components/schemas/blockHash" + }, + "example": { + "value": [ + "k0an0qEORusqQg9ZjKrxa-0Bo0-hQVYLXqWi5LHxg3k" + ] + } + } + }, + "requestBodies": { + "requestKeyArray": { + "description": "Array of request keys", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/requestKey" + } + }, + "examples": { + "empty request body": { + "value": [] + }, + "singleton request body": { + "value": [ + "qx346ILpakzgbNZbE8oHqF5TZQghp-HPcV-0Ptc_n2s" + ] + } + } + } + } + }, + "payloadHashArray": { + "description": "An array of block payload hashes", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/payloadHash" + } + }, + "examples": { + "two": { + "value": { + "value": [ + "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA", + "jcQOWz7K9qKnkUv4Z883D2ZjkFFGgccoSroWGaoogLM" + ] + }, + "summary": "Query two payloads" + }, + "empty": { + "value": [], + "summary": "Query nothing" + } + } + } + } + } + }, + "headers": { + "x-server-timestamp": { + "description": "The time of the clock of the remote node", + "schema": { + "$ref": "#/components/schemas/posixTimestamp" + }, + "example": 1618597601 + }, + "x-chainweb-node-version": { + "description": "The version of the remote chainweb node", + "schema": { + "type": "string" + }, + "example": "2.6" + }, + "x-peer-addr": { + "description": "Host and port of the client as observed by the remote node", + "schema": { + "$ref": "#/components/schemas/hostAddress" + }, + "example": "10.36.1.3:42988" + } + }, + "securitySchemes": {}, + "links": {}, + "callbacks": {}, + "examples": { + "blockHashes": { + "value": [ + "k0an0qEORusqQg9ZjKrxa-0Bo0-hQVYLXqWi5LHxg3k" + ] + }, + "requestKeys": { + "value": [ + "qx346ILpakzgbNZbE8oHqF5TZQghp-HPcV-0Ptc_n2s" + ] + }, + "signedTxText": { + "value": { + "hash": "y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw", + "sigs": [ + { + "sig": "8ddc06b37c496f2cadc4f7412405a80faf3ab07482ff5553b9b5fcc73d1b4121275ad5948d9b4078e553b71f8b42eaf6b24135bf2fb4d5840c16bcdde0e35e0f" + } + ], + "cmd": "{\"networkId\":\"mainnet01\",\"payload\":{\"exec\":{\"data\":{\"account-keyset\":{\"pred\":\"keys-all\",\"keys\":[\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\"]}},\"code\":\"(coin.transfer-create \\\"60241f51ea34e05c61fbea9d\\\" \\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\" (read-keyset \\\"account-keyset\\\") 5007.0000)\"}},\"signers\":[{\"pubKey\":\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\",\"clist\":[{\"args\":[\"60241f51ea34e05c61fbea9d\",\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\",5007],\"name\":\"coin.TRANSFER\"},{\"args\":[],\"name\":\"coin.GAS\"}]}],\"meta\":{\"creationTime\":1618949714,\"ttl\":300,\"gasLimit\":600,\"chainId\":\"0\",\"gasPrice\":1.0e-7,\"sender\":\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\"},\"nonce\":\"\\\"2021-04-20T20:16:13.645Z\\\"\"}" + } + }, + "peers": { + "value": { + "next": "inclusive:3", + "items": [ + { + "address": { + "hostname": "85.238.99.91", + "port": 30004 + }, + "id": "PRLmVUcc9AH3fyfMYiWeC4nV2i1iHwc0-aM7iAO8h18" + }, + { + "address": { + "hostname": "us-w3.chainweb.com", + "port": 443 + }, + "id": null + }, + { + "address": { + "hostname": "95.111.232.151", + "port": 30004 + }, + "id": "DguFKLFMxp12vfl1z3cQIJQlh8xOpeZuBkpJU9Y-VLo" + } + ], + "limit": 3 + } + }, + "blockHashPage": { + "value": { + "next": "inclusive:o1S4NNFhKWg8T1HEkmDvsTH9Ut9l3_qHRpp00yRKZIk", + "items": [ + "k0an0qEORusqQg9ZjKrxa-0Bo0-hQVYLXqWi5LHxg3k", + "vhVa6Deh10RXLRf3L-MSQTYqaL-_IY_mi-v58MjP9R8" + ], + "limit": 2 + } + }, + "blockHashBranchPage": { + "value": { + "next": "inclusive:o1S4NNFhKWg8T1HEkmDvsTH9Ut9l3_qHRpp00yRKZIk", + "items": [ + "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74", + "RClyuyZAacwvPpmLXKbTwrIRXWeUSjiNhJVP2esH8KM" + ], + "limit": 2 + } + }, + "base64HeaderBranchPage": { + "value": { + "next": "inclusive:u9Va7MRkDSOCm0yWpsC2w-4Z0oyEMv-BjofkHeIln6g", + "items": [ + "AAAAAAAAAADX5AyHgcAFAEQpcrsmQGnMLz6Zi1ym08KyEV1nlEo4jYSVT9nrB_CjAwAFAAAA4BMlW68KbggSREOGDeH_oFFoUrpZ0zX0hM0TTdYrEAYKAAAARoxLy8ECsIIWebtW8zZsH1xfRGu4NOuSlgH4cAJLFcwPAAAAsHRn1laXo2DK2_85nOH7apQyC6Vr_gEctSElqdrCC03a4wKcHiVawSuP3DULW8CnWwdh36wAF_eSBwAAAAAAAA3PRGZVm8h4aY9cMgXAQf3QbYSNDUnFxjZnr8FwcknXAAAAAIopfw9LdjBqowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3LgXAAAAAAAFAAAAavQWLYHABQAOBvq0L1PrvEMRggM-QGNWONZ4dclrYKoSoWfaT4j0WoBXSCjagR--", + "AAAAAAAAAAC46tSFgcAFANxrUMH15DY-83DeKwlvDWsj4DY4Sphc5I82jCVSpSuCAwAFAAAAwdorGxUmrIkWyssvz3oHm3uqurfNd5ywiD6NHsZQEr8KAAAA750C1IKC9doZZKtqCckOF8JmIaHMhDfopNobHeJvmXMPAAAA4pgr0U_1kQxou-NIc42nICYqOgLM1Vawamal-HuhLvfa4wKcHiVawSuP3DULW8CnWwdh36wAF_eSBwAAAAAAANdqRLGXd6y6OGwShrFC7vBrIWf_TLCfaYpLnu-q7A7AAAAAAI5IadugqQ5qowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA27gXAAAAAAAFAAAAavQWLYHABQBFGVPEmhORyEQpcrsmQGnMLz6Zi1ym08KyEV1nlEo4jYSVT9nrB_Cj" + ], + "limit": 2 + } + }, + "blockHeaderBranchPage": { + "value": { + "next": "inclusive:3GtQwfXkNj7zcN4rCW8NayPgNjhKmFzkjzaMJVKlK4I", + "items": [ + { + "creationTime": 1619037432636631, + "parent": "RClyuyZAacwvPpmLXKbTwrIRXWeUSjiNhJVP2esH8KM", + "height": 1554652, + "hash": "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74", + "chainId": 0, + "weight": "iil_D0t2MGqjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "featureFlags": 0, + "epochStart": 1619035923346538, + "adjacents": { + "5": "4BMlW68KbggSREOGDeH_oFFoUrpZ0zX0hM0TTdYrEAY", + "10": "RoxLy8ECsIIWebtW8zZsH1xfRGu4NOuSlgH4cAJLFcw", + "15": "sHRn1laXo2DK2_85nOH7apQyC6Vr_gEctSElqdrCC00" + }, + "payloadHash": "Dc9EZlWbyHhpj1wyBcBB_dBthI0NScXGNmevwXBySdc", + "chainwebVersion": "mainnet01", + "target": "2uMCnB4lWsErj9w1C1vAp1sHYd-sABf3kgcAAAAAAAA", + "nonce": "13613065763022308878" + }, + { + "creationTime": 1619037412190904, + "parent": "3GtQwfXkNj7zcN4rCW8NayPgNjhKmFzkjzaMJVKlK4I", + "height": 1554651, + "hash": "RClyuyZAacwvPpmLXKbTwrIRXWeUSjiNhJVP2esH8KM", + "chainId": 0, + "weight": "jkhp26CpDmqjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "featureFlags": 0, + "epochStart": 1619035923346538, + "adjacents": { + "5": "wdorGxUmrIkWyssvz3oHm3uqurfNd5ywiD6NHsZQEr8", + "10": "750C1IKC9doZZKtqCckOF8JmIaHMhDfopNobHeJvmXM", + "15": "4pgr0U_1kQxou-NIc42nICYqOgLM1Vawamal-HuhLvc" + }, + "payloadHash": "12pEsZd3rLo4bBKGsULu8GshZ_9MsJ9pikue76rsDsA", + "chainwebVersion": "mainnet01", + "target": "2uMCnB4lWsErj9w1C1vAp1sHYd-sABf3kgcAAAAAAAA", + "nonce": "14452354234648303941" + } + ], + "limit": 2 + } + }, + "blockHeaderPage": { + "value": { + "next": "inclusive:o1S4NNFhKWg8T1HEkmDvsTH9Ut9l3_qHRpp00yRKZIk", + "items": [ + { + "creationTime": 1602382624629329, + "parent": "HaXABq1PKSKlhncJk0_Mt75_lL7NS3wI627QfXZ_85k", + "height": 1000000, + "hash": "k0an0qEORusqQg9ZjKrxa-0Bo0-hQVYLXqWi5LHxg3k", + "chainId": 0, + "weight": "NQn4BGftuWAeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "featureFlags": 0, + "epochStart": 1602381443331834, + "adjacents": { + "5": "Mpic85rur2MYf3zli8s8bHxTFjriFoMPTr6ZPs8sjxM", + "10": "VBKuhU_hQmuvKlx88A5o-FH0rzNo59NsdxmOGNBQ-yc", + "15": "MItdqgHZxf7j6l0oE8X-G9-VyMbnQmZrtSniuRe_EJ8" + }, + "payloadHash": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA", + "chainwebVersion": "mainnet01", + "target": "QrcsbEm-3WjyCGAGlzIEhLEN3ZMWORoyYy8AAAAAAAA", + "nonce": "13095611958898437" + }, + { + "creationTime": 1602382678045236, + "parent": "k0an0qEORusqQg9ZjKrxa-0Bo0-hQVYLXqWi5LHxg3k", + "height": 1000001, + "hash": "vhVa6Deh10RXLRf3L-MSQTYqaL-_IY_mi-v58MjP9R8", + "chainId": 0, + "weight": "bOkHN2JUv2AeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "featureFlags": 0, + "epochStart": 1602381443331834, + "adjacents": { + "5": "ALcxv1ZiwwQ_QX9eOBZMbzIop6n7XtveS1FqOFwyvGM", + "10": "C76ElC60qXSJQCHePpzzJxsCYvvrqvmkoHPyZnex-4Q", + "15": "Kv0sz_rTANjoiJwMrdZFCJNFwdH0U_M5ouwMr3BXBfo" + }, + "payloadHash": "smUiDW9jfD_0vrdt4-fXKT_lqC90RsgEGObdp3FznFY", + "chainwebVersion": "mainnet01", + "target": "QrcsbEm-3WjyCGAGlzIEhLEN3ZMWORoyYy8AAAAAAAA", + "nonce": "110239794631051275" + } + ], + "limit": 2 + } + }, + "base64HeaderPage": { + "value": { + "next": "inclusive:o1S4NNFhKWg8T1HEkmDvsTH9Ut9l3_qHRpp00yRKZIk", + "items": [ + "AAAAAAAAAABRoiLHW7EFAB2lwAatTykipYZ3CZNPzLe-f5S-zUt8COtu0H12f_OZAwAFAAAAMpic85rur2MYf3zli8s8bHxTFjriFoMPTr6ZPs8sjxMKAAAAVBKuhU_hQmuvKlx88A5o-FH0rzNo59NsdxmOGNBQ-ycPAAAAMItdqgHZxf7j6l0oE8X-G9-VyMbnQmZrtSniuRe_EJ9CtyxsSb7daPIIYAaXMgSEsQ3dkxY5GjJjLwAAAAAAABqWlmx5B6wo0YWPIShNKmdVrAQWht2P85BS1drGLpkAAAAAADUJ-ARn7blgHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEIPAAAAAAAFAAAA-na5gFuxBQAFL-3CY4YuAJNGp9KhDkbrKkIPWYyq8WvtAaNPoUFWC16louSx8YN5", + "AAAAAAAAAAA0slHKW7EFAJNGp9KhDkbrKkIPWYyq8WvtAaNPoUFWC16louSx8YN5AwAFAAAAALcxv1ZiwwQ_QX9eOBZMbzIop6n7XtveS1FqOFwyvGMKAAAAC76ElC60qXSJQCHePpzzJxsCYvvrqvmkoHPyZnex-4QPAAAAKv0sz_rTANjoiJwMrdZFCJNFwdH0U_M5ouwMr3BXBfpCtyxsSb7daPIIYAaXMgSEsQ3dkxY5GjJjLwAAAAAAALJlIg1vY3w_9L63bePn1yk_5agvdEbIBBjm3adxc5xWAAAAAGzpBzdiVL9gHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQUIPAAAAAAAFAAAA-na5gFuxBQALiBhXgqaHAb4VWug3oddEVy0X9y_jEkE2Kmi_vyGP5ovr-fDIz_Uf" + ], + "limit": 2 + } + }, + "info": { + "value": { + "nodeNumberOfChains": 20, + "nodeApiVersion": "0.0", + "nodeChains": [ + "12", + "13", + "14", + "15", + "8", + "9", + "10", + "11", + "4", + "5", + "6", + "7", + "0", + "16", + "1", + "17", + "2", + "18", + "3", + "19" + ], + "nodeVersion": "mainnet01", + "nodeGraphHistory": [ + [ + 0, + [ + [ + 0, + [ + 5, + 2, + 3 + ] + ], + [ + 1, + [ + 4, + 6, + 3 + ] + ], + [ + 2, + [ + 4, + 7, + 0 + ] + ], + [ + 3, + [ + 8, + 0, + 1 + ] + ], + [ + 4, + [ + 9, + 1, + 2 + ] + ], + [ + 5, + [ + 9, + 6, + 0 + ] + ], + [ + 6, + [ + 5, + 7, + 1 + ] + ], + [ + 7, + [ + 8, + 6, + 2 + ] + ], + [ + 8, + [ + 9, + 7, + 3 + ] + ], + [ + 9, + [ + 8, + 4, + 5 + ] + ] + ] + ], + [ + 852054, + [ + [ + 0, + [ + 15, + 10, + 5 + ] + ], + [ + 1, + [ + 11, + 6, + 16 + ] + ], + [ + 2, + [ + 12, + 7, + 17 + ] + ], + [ + 3, + [ + 13, + 8, + 18 + ] + ], + [ + 4, + [ + 14, + 9, + 19 + ] + ], + [ + 5, + [ + 8, + 7, + 0 + ] + ], + [ + 6, + [ + 8, + 9, + 1 + ] + ], + [ + 7, + [ + 9, + 5, + 2 + ] + ], + [ + 8, + [ + 5, + 6, + 3 + ] + ], + [ + 9, + [ + 4, + 6, + 7 + ] + ], + [ + 10, + [ + 11, + 0, + 19 + ] + ], + [ + 11, + [ + 12, + 10, + 1 + ] + ], + [ + 12, + [ + 13, + 11, + 2 + ] + ], + [ + 13, + [ + 12, + 14, + 3 + ] + ], + [ + 14, + [ + 13, + 15, + 4 + ] + ], + [ + 15, + [ + 14, + 0, + 16 + ] + ], + [ + 16, + [ + 15, + 1, + 17 + ] + ], + [ + 17, + [ + 16, + 2, + 18 + ] + ], + [ + 18, + [ + 17, + 3, + 19 + ] + ], + [ + 19, + [ + 10, + 4, + 18 + ] + ] + ] + ] + ] + } + }, + "cut": { + "value": { + "origin": null, + "height": 30798466, + "weight": "b0wYplmNiTBXCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "hashes": { + "0": { + "height": 1539923, + "hash": "qEaSmWt_tDcJC9AGbgWY9x12LW5VED7hGgfyz9x_S3w" + }, + "1": { + "height": 1539923, + "hash": "TJuC6nfhamfD517gspAZmqD9umR71nAgttDOi1JbBHw" + }, + "2": { + "height": 1539924, + "hash": "4ineCWfnO1rneWuBMLPzqTl2HF_sZpypT_3TEzf3VLc" + }, + "3": { + "height": 1539924, + "hash": "ZEOMXB2ByqzL2HfYVKIZKAnoe4wIeJ2SaltnXDir59k" + }, + "4": { + "height": 1539923, + "hash": "0g0rOoSznVW2BJDBmK0Lbxz22F-sxTZUNIrUs_Q8Ye4" + }, + "5": { + "height": 1539923, + "hash": "5y_TL-clnF_wELMBKyJk0Sz8RVShw_bGQETJdrMkADA" + }, + "6": { + "height": 1539923, + "hash": "YkQKv6P4_C4jRM3RqKK9FWPxIneeLzlkKQS9ATAQYRk" + }, + "7": { + "height": 1539923, + "hash": "j_hJ9iiH_ATyeQeeRN3auGXjbBWiFgnTU0dYPIz8cKM" + }, + "8": { + "height": 1539924, + "hash": "s7c3B55VbDsS6EJ-nc9S5k2kNbPOBGI8xxF3vUg4d4Q" + }, + "9": { + "height": 1539922, + "hash": "bowQf63xSY9owHKhK1yGee2Q0Fn8yL_oCLaEUn-CGoA" + }, + "10": { + "height": 1539924, + "hash": "uP-pHW4QKrV9fN1mlDGwKuaiIDlJW7xYSj1nW53EHM4" + }, + "11": { + "height": 1539924, + "hash": "TIhegjZ0GEC73T4m0BVuFtfLNGuS56IUWEuf93AJ5UU" + }, + "12": { + "height": 1539923, + "hash": "-j1qcAS9Fs-WQmc3WEhzZ96VojxnlIA2TFpfyIv31Zs" + }, + "13": { + "height": 1539923, + "hash": "S-4TqMgWGlK1k33XRlU9w0Lfwr0RvkO5Jn78Au1OglM" + }, + "14": { + "height": 1539923, + "hash": "xSuULf--S4TrgYNz82deaGhnPLWrg3pXkynGeUPUGwA" + }, + "15": { + "height": 1539923, + "hash": "jsc9rugvcHXDiBAuoO9_j8R_b_jchtJJ8b5596i8wVg" + }, + "16": { + "height": 1539923, + "hash": "qs1aEY8kSxfUBb_JRVswv5dYINRXBjGJteC-6RC1hjc" + }, + "17": { + "height": 1539924, + "hash": "xzVBXaQxzlUfUrakDgppUubQBRXGh-Uy0HBdMNwCq_Y" + }, + "18": { + "height": 1539924, + "hash": "4VOHPAqwioySYRycdl5MxfscQHwtlwwCAt7AySYQT98" + }, + "19": { + "height": 1539923, + "hash": "1PrRg20XyQ_2cfgGOgNK9K-cqIJ1vO8-A-RJlfN5m00" + } + }, + "id": "BBz7KeurYTeQ0hMGbwUbQC84cRbVcacoDQTye-3qkXI", + "instance": "mainnet01" + } + }, + "payloadHash": { + "value": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA" + }, + "payloadHashes": { + "value": [ + "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA", + "jcQOWz7K9qKnkUv4Z883D2ZjkFFGgccoSroWGaoogLM" + ] + }, + "payloads": { + "value": [ + { + "transactions": [], + "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + "transactionsHash": "nT0j4xw2woMkdXXaopdurXIn24OG-jNMqQzUGfxV_MA", + "outputsHash": "4pXRrZ2K0_V0iGAxQCKrKdLjQTBZHBOQS7P-47kdnhY", + "payloadHash": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA" + }, + { + "transactions": [ + "eyJoYXNoIjoiMi16Q3dmRFZZR010WHljd2pTLXRlNzh5U3l3T3JXcjNSdUhiQlJnNDdhRSIsInNpZ3MiOlt7InNpZyI6ImZiMTVkNzkyYTNkNDM1MDI5ODJmOGQ1MGUyMzA1NTI5OWEwZjdhMWRmMWE4YjUyMmE5NTMxNWUyZDljY2MyNmE1MzI4M2I5YTNhNDM5ZWE0ZGY4MGM1ZTIwMjg4NDhjNjFhMWY0MGM5OWIyOTYzOWM0NGNkYTgwMzBmYmViYjBjIn1dLCJjbWQiOiJ7XCJuZXR3b3JrSWRcIjpcIm1haW5uZXQwMVwiLFwicGF5bG9hZFwiOntcImV4ZWNcIjp7XCJkYXRhXCI6e30sXCJjb2RlXCI6XCIoY29pbi50cmFuc2ZlciBcXFwiZTc1NzU4ZGQyYTFjNTk2NDRjMjJlMDQyYzZlYzA3NTI2ZWE0ZTU3MTU0ZjlkYmMyMDc2ZThhODRhYzE5NGYzMlxcXCIgXFxcIjQ2NzdhMDllYTE2MDJlNGUwOWZlMDFlYjExOTZjZjQ3YzBmNDRhYTQ0YWFjOTAzZDVmNjFiZTdkYTM0MjUxMjhcXFwiIDMuNzc2KVwifX0sXCJzaWduZXJzXCI6W3tcInB1YktleVwiOlwiZTc1NzU4ZGQyYTFjNTk2NDRjMjJlMDQyYzZlYzA3NTI2ZWE0ZTU3MTU0ZjlkYmMyMDc2ZThhODRhYzE5NGYzMlwiLFwiY2xpc3RcIjpbe1wiYXJnc1wiOltdLFwibmFtZVwiOlwiY29pbi5HQVNcIn0se1wiYXJnc1wiOltcImU3NTc1OGRkMmExYzU5NjQ0YzIyZTA0MmM2ZWMwNzUyNmVhNGU1NzE1NGY5ZGJjMjA3NmU4YTg0YWMxOTRmMzJcIixcIjQ2NzdhMDllYTE2MDJlNGUwOWZlMDFlYjExOTZjZjQ3YzBmNDRhYTQ0YWFjOTAzZDVmNjFiZTdkYTM0MjUxMjhcIiwzLjc3Nl0sXCJuYW1lXCI6XCJjb2luLlRSQU5TRkVSXCJ9XX1dLFwibWV0YVwiOntcImNyZWF0aW9uVGltZVwiOjE2MDIzODI4MTQsXCJ0dGxcIjoyODgwMCxcImdhc0xpbWl0XCI6NjAwLFwiY2hhaW5JZFwiOlwiMFwiLFwiZ2FzUHJpY2VcIjoxLjBlLTUsXCJzZW5kZXJcIjpcImU3NTc1OGRkMmExYzU5NjQ0YzIyZTA0MmM2ZWMwNzUyNmVhNGU1NzE1NGY5ZGJjMjA3NmU4YTg0YWMxOTRmMzJcIn0sXCJub25jZVwiOlwiXFxcIjIwMjAtMTAtMTFUMDI6MjE6MTQuMTk0WlxcXCJcIn0ifQ" + ], + "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + "transactionsHash": "lWcQRlj3MV7FSem8P4G-8GMRf1-O7zQqi_AwmWnk-N0", + "outputsHash": "9BzXZbhjSSevp4K0bYFqi1GdLjeX_DB-4u1T5Em8abs", + "payloadHash": "jcQOWz7K9qKnkUv4Z883D2ZjkFFGgccoSroWGaoogLM" + } + ] + }, + "emptyPayload": { + "value": { + "transactions": [], + "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + "transactionsHash": "nT0j4xw2woMkdXXaopdurXIn24OG-jNMqQzUGfxV_MA", + "outputsHash": "4pXRrZ2K0_V0iGAxQCKrKdLjQTBZHBOQS7P-47kdnhY", + "payloadHash": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA", + "coinbase": "eyJnYXMiOjAsInJlc3VsdCI6eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6IldyaXRlIHN1Y2NlZWRlZCJ9LCJyZXFLZXkiOiJJa2hoV0VGQ2NURlFTMU5MYkdodVkwcHJNRjlOZERjMVgyeE1OMDVUTTNkSk5qSTNVV1pZV2w4NE5Xc2kiLCJsb2dzIjoiZ3Noak1kWFJrVGxKYmIxalZkQWJ6SVVDcGpQb1JBQ2pEbExzRzBXNkJEMCIsIm1ldGFEYXRhIjpudWxsLCJjb250aW51YXRpb24iOm51bGwsInR4SWQiOjEyNzIzNTB9" + } + }, + "payloadWithTransactions": { + "value": { + "transactions": [ + [ + "eyJoYXNoIjoiMi16Q3dmRFZZR010WHljd2pTLXRlNzh5U3l3T3JXcjNSdUhiQlJnNDdhRSIsInNpZ3MiOlt7InNpZyI6ImZiMTVkNzkyYTNkNDM1MDI5ODJmOGQ1MGUyMzA1NTI5OWEwZjdhMWRmMWE4YjUyMmE5NTMxNWUyZDljY2MyNmE1MzI4M2I5YTNhNDM5ZWE0ZGY4MGM1ZTIwMjg4NDhjNjFhMWY0MGM5OWIyOTYzOWM0NGNkYTgwMzBmYmViYjBjIn1dLCJjbWQiOiJ7XCJuZXR3b3JrSWRcIjpcIm1haW5uZXQwMVwiLFwicGF5bG9hZFwiOntcImV4ZWNcIjp7XCJkYXRhXCI6e30sXCJjb2RlXCI6XCIoY29pbi50cmFuc2ZlciBcXFwiZTc1NzU4ZGQyYTFjNTk2NDRjMjJlMDQyYzZlYzA3NTI2ZWE0ZTU3MTU0ZjlkYmMyMDc2ZThhODRhYzE5NGYzMlxcXCIgXFxcIjQ2NzdhMDllYTE2MDJlNGUwOWZlMDFlYjExOTZjZjQ3YzBmNDRhYTQ0YWFjOTAzZDVmNjFiZTdkYTM0MjUxMjhcXFwiIDMuNzc2KVwifX0sXCJzaWduZXJzXCI6W3tcInB1YktleVwiOlwiZTc1NzU4ZGQyYTFjNTk2NDRjMjJlMDQyYzZlYzA3NTI2ZWE0ZTU3MTU0ZjlkYmMyMDc2ZThhODRhYzE5NGYzMlwiLFwiY2xpc3RcIjpbe1wiYXJnc1wiOltdLFwibmFtZVwiOlwiY29pbi5HQVNcIn0se1wiYXJnc1wiOltcImU3NTc1OGRkMmExYzU5NjQ0YzIyZTA0MmM2ZWMwNzUyNmVhNGU1NzE1NGY5ZGJjMjA3NmU4YTg0YWMxOTRmMzJcIixcIjQ2NzdhMDllYTE2MDJlNGUwOWZlMDFlYjExOTZjZjQ3YzBmNDRhYTQ0YWFjOTAzZDVmNjFiZTdkYTM0MjUxMjhcIiwzLjc3Nl0sXCJuYW1lXCI6XCJjb2luLlRSQU5TRkVSXCJ9XX1dLFwibWV0YVwiOntcImNyZWF0aW9uVGltZVwiOjE2MDIzODI4MTQsXCJ0dGxcIjoyODgwMCxcImdhc0xpbWl0XCI6NjAwLFwiY2hhaW5JZFwiOlwiMFwiLFwiZ2FzUHJpY2VcIjoxLjBlLTUsXCJzZW5kZXJcIjpcImU3NTc1OGRkMmExYzU5NjQ0YzIyZTA0MmM2ZWMwNzUyNmVhNGU1NzE1NGY5ZGJjMjA3NmU4YTg0YWMxOTRmMzJcIn0sXCJub25jZVwiOlwiXFxcIjIwMjAtMTAtMTFUMDI6MjE6MTQuMTk0WlxcXCJcIn0ifQ", + "eyJnYXMiOjU3MiwicmVzdWx0Ijp7InN0YXR1cyI6InN1Y2Nlc3MiLCJkYXRhIjoiV3JpdGUgc3VjY2VlZGVkIn0sInJlcUtleSI6IjItekN3ZkRWWUdNdFh5Y3dqUy10ZTc4eVN5d09yV3IzUnVIYkJSZzQ3YUUiLCJsb2dzIjoiSU1ra1VFZmVGak45bFQxZ0gtX2ZNT1dDRklrU1d6aVNTZHF2eEo4dS16RSIsIm1ldGFEYXRhIjpudWxsLCJjb250aW51YXRpb24iOm51bGwsInR4SWQiOjEyNzIzNzJ9" + ] + ], + "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + "transactionsHash": "lWcQRlj3MV7FSem8P4G-8GMRf1-O7zQqi_AwmWnk-N0", + "outputsHash": "9BzXZbhjSSevp4K0bYFqi1GdLjeX_DB-4u1T5Em8abs", + "payloadHash": "jcQOWz7K9qKnkUv4Z883D2ZjkFFGgccoSroWGaoogLM", + "coinbase": "eyJnYXMiOjAsInJlc3VsdCI6eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6IldyaXRlIHN1Y2NlZWRlZCJ9LCJyZXFLZXkiOiJJbkV4WDFkUk16SnliRmhCWW1KcU9WTnZkMXB2YmtabmNHRXdlRnBXUWtKdmNUWTJiRk0xY0RSQ1ZVVWkiLCJsb2dzIjoiSVc0N0QxTXFMVW9mRnNKbWpoWGdDZnhnb2Fzb0xTc05YZUFiOFRPb2NCNCIsIm1ldGFEYXRhIjpudWxsLCJjb250aW51YXRpb24iOm51bGwsInR4SWQiOjEyNzIzNzB9" + } + }, + "payloadsWithOutputs": { + "value": [ + { + "$ref": "#/components/examples/emptyPayload" + }, + { + "$ref": "#/components/examples/payloadWithTransactions" + } + ] + }, + "nodeConfig": { + "value": { + "allowReadsInLocal": false, + "rosetta": true, + "throttling": { + "local": 1, + "mining": 2, + "global": 200, + "putPeer": 21 + }, + "serviceApi": { + "interface": "invalid", + "port": 0 + }, + "validateHashesOnReplay": false, + "chainwebVersion": "mainnet01", + "pactQueueSize": 2000, + "mining": { + "coordination": { + "enabled": false, + "updateStreamTimeout": 240, + "limit": 1200, + "updateStreamLimit": 2000, + "miners": [] + }, + "nodeMining": { + "miner": { + "account": "", + "predicate": "keys-all", + "public-keys": [] + }, + "enabled": false + } + }, + "p2p": { + "peer": { + "certificateChainFile": null, + "key": null, + "interface": "*", + "certificateChain": null, + "hostaddress": { + "hostname": "34.70.108.163", + "port": 1789 + }, + "keyFile": null + }, + "maxPeerCount": 100, + "private": false, + "ignoreBootstrapNodes": false, + "maxSessionCount": 8, + "bootstrapReachability": 0.5, + "sessionTimeout": 300, + "peers": [ + { + "address": { + "hostname": "us-e1.chainweb.com", + "port": 443 + }, + "id": null + }, + { + "address": { + "hostname": "us-w1.chainweb.com", + "port": 443 + }, + "id": null + } + ] + }, + "transactionIndex": { + "enabled": true, + "configuration": {} + }, + "gasLimitOfBlock": 150000, + "reorgLimit": 480, + "headerStream": true, + "mempoolP2p": { + "enabled": true, + "configuration": { + "pollInterval": 30, + "maxSessionCount": 6, + "sessionTimeout": 240 + } + }, + "reintroTxs": true, + "cuts": { + "pruneChainDatabase": "none", + "fetchTimeout": 3000000, + "initialCutHeightLimit": null + } + } + } + } + }, + "paths": { + "/cut": { + "summary": "Cut Endpoints", + "description": "A cut represents a distributed state of a chainweb. It references one\nblock header for each chain, such that those blocks are pairwise\nconcurrent.\n\nTwo blocks from two different chains are said to be concurrent if either\none of them is an adjacent parent (is a direct dependency) of the other or\nif the blocks do not depend at all on each other.\n", + "get": { + "tags": [ + "cut" + ], + "summary": "Query the current cut", + "parameters": [ + { + "name": "maxheight", + "in": "query", + "description": "Maximum cut height of the returned cut", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + } + } + ], + "responses": { + "200": { + "description": "The current cut", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/cut" + }, + "example": { + "value": { + "origin": null, + "height": 30798466, + "weight": "b0wYplmNiTBXCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "hashes": { + "0": { + "height": 1539923, + "hash": "qEaSmWt_tDcJC9AGbgWY9x12LW5VED7hGgfyz9x_S3w" + }, + "1": { + "height": 1539923, + "hash": "TJuC6nfhamfD517gspAZmqD9umR71nAgttDOi1JbBHw" + }, + "2": { + "height": 1539924, + "hash": "4ineCWfnO1rneWuBMLPzqTl2HF_sZpypT_3TEzf3VLc" + }, + "3": { + "height": 1539924, + "hash": "ZEOMXB2ByqzL2HfYVKIZKAnoe4wIeJ2SaltnXDir59k" + }, + "4": { + "height": 1539923, + "hash": "0g0rOoSznVW2BJDBmK0Lbxz22F-sxTZUNIrUs_Q8Ye4" + }, + "5": { + "height": 1539923, + "hash": "5y_TL-clnF_wELMBKyJk0Sz8RVShw_bGQETJdrMkADA" + }, + "6": { + "height": 1539923, + "hash": "YkQKv6P4_C4jRM3RqKK9FWPxIneeLzlkKQS9ATAQYRk" + }, + "7": { + "height": 1539923, + "hash": "j_hJ9iiH_ATyeQeeRN3auGXjbBWiFgnTU0dYPIz8cKM" + }, + "8": { + "height": 1539924, + "hash": "s7c3B55VbDsS6EJ-nc9S5k2kNbPOBGI8xxF3vUg4d4Q" + }, + "9": { + "height": 1539922, + "hash": "bowQf63xSY9owHKhK1yGee2Q0Fn8yL_oCLaEUn-CGoA" + }, + "10": { + "height": 1539924, + "hash": "uP-pHW4QKrV9fN1mlDGwKuaiIDlJW7xYSj1nW53EHM4" + }, + "11": { + "height": 1539924, + "hash": "TIhegjZ0GEC73T4m0BVuFtfLNGuS56IUWEuf93AJ5UU" + }, + "12": { + "height": 1539923, + "hash": "-j1qcAS9Fs-WQmc3WEhzZ96VojxnlIA2TFpfyIv31Zs" + }, + "13": { + "height": 1539923, + "hash": "S-4TqMgWGlK1k33XRlU9w0Lfwr0RvkO5Jn78Au1OglM" + }, + "14": { + "height": 1539923, + "hash": "xSuULf--S4TrgYNz82deaGhnPLWrg3pXkynGeUPUGwA" + }, + "15": { + "height": 1539923, + "hash": "jsc9rugvcHXDiBAuoO9_j8R_b_jchtJJ8b5596i8wVg" + }, + "16": { + "height": 1539923, + "hash": "qs1aEY8kSxfUBb_JRVswv5dYINRXBjGJteC-6RC1hjc" + }, + "17": { + "height": 1539924, + "hash": "xzVBXaQxzlUfUrakDgppUubQBRXGh-Uy0HBdMNwCq_Y" + }, + "18": { + "height": 1539924, + "hash": "4VOHPAqwioySYRycdl5MxfscQHwtlwwCAt7AySYQT98" + }, + "19": { + "height": 1539923, + "hash": "1PrRg20XyQ_2cfgGOgNK9K-cqIJ1vO8-A-RJlfN5m00" + } + }, + "id": "BBz7KeurYTeQ0hMGbwUbQC84cRbVcacoDQTye-3qkXI", + "instance": "mainnet01" + } + } + } + } + } + } + }, + "put": { + "summary": "Publish a cut", + "description": "Publish a cut to a Chainweb node.\n\nThe cut must contain an origin property that is not `null`. The receiving node\nwill first try to obtain all missing dependencies from the node that is\nindicated in by the origin property before searching for the dependencies in the\nP2P network.\n", + "tags": [ + "cut" + ], + "requestBody": { + "description": "A cut with an origin property that is not `null`.", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/cut" + }, + { + "required": [ + "origin" + ] + } + ] + }, + "example": { + "value": { + "origin": null, + "height": 30798466, + "weight": "b0wYplmNiTBXCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "hashes": { + "0": { + "height": 1539923, + "hash": "qEaSmWt_tDcJC9AGbgWY9x12LW5VED7hGgfyz9x_S3w" + }, + "1": { + "height": 1539923, + "hash": "TJuC6nfhamfD517gspAZmqD9umR71nAgttDOi1JbBHw" + }, + "2": { + "height": 1539924, + "hash": "4ineCWfnO1rneWuBMLPzqTl2HF_sZpypT_3TEzf3VLc" + }, + "3": { + "height": 1539924, + "hash": "ZEOMXB2ByqzL2HfYVKIZKAnoe4wIeJ2SaltnXDir59k" + }, + "4": { + "height": 1539923, + "hash": "0g0rOoSznVW2BJDBmK0Lbxz22F-sxTZUNIrUs_Q8Ye4" + }, + "5": { + "height": 1539923, + "hash": "5y_TL-clnF_wELMBKyJk0Sz8RVShw_bGQETJdrMkADA" + }, + "6": { + "height": 1539923, + "hash": "YkQKv6P4_C4jRM3RqKK9FWPxIneeLzlkKQS9ATAQYRk" + }, + "7": { + "height": 1539923, + "hash": "j_hJ9iiH_ATyeQeeRN3auGXjbBWiFgnTU0dYPIz8cKM" + }, + "8": { + "height": 1539924, + "hash": "s7c3B55VbDsS6EJ-nc9S5k2kNbPOBGI8xxF3vUg4d4Q" + }, + "9": { + "height": 1539922, + "hash": "bowQf63xSY9owHKhK1yGee2Q0Fn8yL_oCLaEUn-CGoA" + }, + "10": { + "height": 1539924, + "hash": "uP-pHW4QKrV9fN1mlDGwKuaiIDlJW7xYSj1nW53EHM4" + }, + "11": { + "height": 1539924, + "hash": "TIhegjZ0GEC73T4m0BVuFtfLNGuS56IUWEuf93AJ5UU" + }, + "12": { + "height": 1539923, + "hash": "-j1qcAS9Fs-WQmc3WEhzZ96VojxnlIA2TFpfyIv31Zs" + }, + "13": { + "height": 1539923, + "hash": "S-4TqMgWGlK1k33XRlU9w0Lfwr0RvkO5Jn78Au1OglM" + }, + "14": { + "height": 1539923, + "hash": "xSuULf--S4TrgYNz82deaGhnPLWrg3pXkynGeUPUGwA" + }, + "15": { + "height": 1539923, + "hash": "jsc9rugvcHXDiBAuoO9_j8R_b_jchtJJ8b5596i8wVg" + }, + "16": { + "height": 1539923, + "hash": "qs1aEY8kSxfUBb_JRVswv5dYINRXBjGJteC-6RC1hjc" + }, + "17": { + "height": 1539924, + "hash": "xzVBXaQxzlUfUrakDgppUubQBRXGh-Uy0HBdMNwCq_Y" + }, + "18": { + "height": 1539924, + "hash": "4VOHPAqwioySYRycdl5MxfscQHwtlwwCAt7AySYQT98" + }, + "19": { + "height": 1539923, + "hash": "1PrRg20XyQ_2cfgGOgNK9K-cqIJ1vO8-A-RJlfN5m00" + } + }, + "id": "BBz7KeurYTeQ0hMGbwUbQC84cRbVcacoDQTye-3qkXI", + "instance": "mainnet01" + } + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "The cut was added to the cut processing pipeline of the remote node", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + } + }, + "401": { + "description": "The requester is not a peer of this node, and thus not allowed to send it cuts", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + } + } + } + } + }, + "/cut/peer": { + "get": { + "summary": "Get Cut-Network Peer Info", + "tags": [ + "peer" + ], + "parameters": [ + { + "$ref": "#/components/parameters/limit" + }, + { + "$ref": "#/components/parameters/next" + } + ], + "responses": { + "200": { + "description": "Peers from the peer database of the remote node", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "properties": { + "items": { + "description": "Array of peers", + "items": { + "$ref": "#/components/schemas/peer" + } + } + } + }, + { + "$ref": "#/components/schemas/page" + } + ] + }, + "example": { + "value": { + "next": "inclusive:3", + "items": [ + { + "address": { + "hostname": "85.238.99.91", + "port": 30004 + }, + "id": "PRLmVUcc9AH3fyfMYiWeC4nV2i1iHwc0-aM7iAO8h18" + }, + { + "address": { + "hostname": "us-w3.chainweb.com", + "port": 443 + }, + "id": null + }, + { + "address": { + "hostname": "95.111.232.151", + "port": 30004 + }, + "id": "DguFKLFMxp12vfl1z3cQIJQlh8xOpeZuBkpJU9Y-VLo" + } + ], + "limit": 3 + } + } + } + } + } + } + }, + "put": { + "summary": "Put Cut-Network Peer Info", + "tags": [ + "peer" + ], + "requestBody": { + "description": "The peer that is added to the peer database of the cut P2P network of\nthe remote host.\n", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/peer" + }, + { + "properties": { + "id": { + "nullable": true + } + } + } + ] + } + } + } + }, + "responses": { + "204": { + "description": "The peer got added to the peer database of the remote node.", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + } + }, + "400": { + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "description": "The request is invalid. It is either malformed or the provided peer\nis not reachable.\n\nBefore the remote node adds a peer to its peer database it checks\nwhether the peer can be reached via the provided address. If this\ncheck fails an error is returned.\n", + "content": { + "text/plain": { + "description": "The reason for the failure.", + "example": "Invalid hostaddress: IsNotReachable (PeerInfo {_peerId = Nothing, _peerAddr = HostAddress {_hostAddressHost = us-w1.chainweb.com, _hostAddressPort = 444}}) \"\\\"HttpExceptionRequest Request {\\\\n host = \\\\\\\"us-w1.chainweb.com\\\\\\\"\\\\n port = 444\\\\n secure = True\\\\n requestHeaders = [(\\\\\\\"X-Chainweb-Node-Version\\\\\\\",\\\\\\\"2.6\\\\\\\")]\\\\n path = \\\\\\\"/chainweb/0.0/mainnet01/cut/peer\\\\\\\"\\\\n queryString = \\\\\\\"\\\\\\\"\\\\n method = \\\\\\\"GET\\\\\\\"\\\\n proxy = Nothing\\\\n rawBody = False\\\\n redirectCount = 10\\\\n responseTimeout = ResponseTimeoutMicro 2000000\\\\n requestVersion = HTTP/1.1\\\\n}\\\\n ConnectionTimeout\\\"\"" + } + } + } + } + } + }, + "/chain/{chain}/hash": { + "get": { + "summary": "Get Block Hashes", + "tags": [ + "blockhash" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + }, + { + "$ref": "#/components/parameters/limit" + }, + { + "$ref": "#/components/parameters/next" + }, + { + "$ref": "#/components/parameters/minheight" + }, + { + "$ref": "#/components/parameters/maxheight" + } + ], + "responses": { + "200": { + "description": "A page of a collection of block hashes in **ascending** order\nthat satisfies query parameters. Any block hash from the chain\ndatabase is returned. **This includes hashes of orphaned blocks.**\n", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "properties": { + "items": { + "description": "Array of block hashes", + "items": { + "$ref": "#/components/schemas/blockHash" + } + } + } + }, + { + "$ref": "#/components/schemas/page" + } + ] + }, + "example": { + "value": { + "next": "inclusive:o1S4NNFhKWg8T1HEkmDvsTH9Ut9l3_qHRpp00yRKZIk", + "items": [ + "k0an0qEORusqQg9ZjKrxa-0Bo0-hQVYLXqWi5LHxg3k", + "vhVa6Deh10RXLRf3L-MSQTYqaL-_IY_mi-v58MjP9R8" + ], + "limit": 2 + } + } + } + } + }, + "404": { + "description": "A parameter indicated a nonexistent block height.\n", + "content": { + "application/json": { + "schema": { + "properties": { + "reason": { + "type": "string" + }, + "key": { + "$ref": "#/components/schemas/blockHash" + } + } + } + } + } + } + } + } + }, + "/chain/{chain}/hash/branch": { + "post": { + "summary": "Get Block Hash Branches", + "description": "A page of block hashes from branches of the block chain in\n**descending** order.\n\nOnly blocks are returned that are ancestors of the some block in the\nset of upper bounds and are not ancestors of any block in the set of\nlower bounds.\n", + "tags": [ + "blockhash" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + }, + { + "$ref": "#/components/parameters/limit" + }, + { + "$ref": "#/components/parameters/next" + }, + { + "$ref": "#/components/parameters/minheight" + }, + { + "$ref": "#/components/parameters/maxheight" + } + ], + "requestBody": { + "description": "Upper and lower bounds of the queried branches", + "content": { + "application/json": { + "schema": { + "properties": { + "lower": { + "description": "No block hashes are returned that are predecessors of any\nblock with a hash from this array.\n", + "type": "array", + "items": { + "$ref": "#/components/schemas/blockHash" + } + }, + "upper": { + "description": "Returned block hashes are predecessors of a block with an\nhash from this array. This includes blocks with hashes from\nthis array.\n", + "type": "array", + "items": { + "$ref": "#/components/schemas/blockHash" + } + } + } + }, + "examples": { + "singletonLimited": { + "value": { + "lower": [ + "RClyuyZAacwvPpmLXKbTwrIRXWeUSjiNhJVP2esH8KM" + ], + "upper": [ + "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74" + ] + }, + "summary": "Ancestors of block that are not acestors of another block" + }, + "singleton": { + "value": { + "lower": [], + "upper": [ + "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74" + ] + }, + "summary": "Ancestors of one block" + }, + "empty": { + "value": { + "lower": [], + "upper": [] + }, + "summary": "Empty branch" + }, + "empty2": { + "value": { + "lower": [ + "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74" + ], + "upper": [ + "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74" + ] + }, + "summary": "Another example that returns an empty page" + } + } + } + } + }, + "responses": { + "200": { + "description": "The requested block hashes", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "properties": { + "items": { + "description": "Array of block hashes", + "items": { + "$ref": "#/components/schemas/blockHash" + } + } + } + }, + { + "$ref": "#/components/schemas/page" + } + ] + }, + "example": { + "value": { + "next": "inclusive:o1S4NNFhKWg8T1HEkmDvsTH9Ut9l3_qHRpp00yRKZIk", + "items": [ + "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74", + "RClyuyZAacwvPpmLXKbTwrIRXWeUSjiNhJVP2esH8KM" + ], + "limit": 2 + } + } + } + } + }, + "404": { + "description": "The requested block hashes could not be found", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "properties": { + "reason": { + "type": "string" + }, + "key": { + "$ref": "#/components/schemas/blockHash" + } + } + } + } + } + } + } + } + }, + "/chain/{chain}/header": { + "get": { + "summary": "Get Block Headers", + "description": "A page of a collection of block headers in **ascending** order\nthat satisfies query parameters. Any block header from the chain\ndatabase is returned. **This includes headers of orphaned blocks.**\n", + "tags": [ + "header" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + }, + { + "$ref": "#/components/parameters/limit" + }, + { + "$ref": "#/components/parameters/next" + }, + { + "$ref": "#/components/parameters/minheight" + }, + { + "$ref": "#/components/parameters/maxheight" + } + ], + "responses": { + "200": { + "description": "The requested block headers", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "properties": { + "items": { + "description": "Array of base64 encoded block headers", + "type": "array", + "items": { + "$ref": "#/components/schemas/base64Header" + } + } + } + }, + { + "$ref": "#/components/schemas/page" + } + ] + }, + "example": { + "value": { + "next": "inclusive:o1S4NNFhKWg8T1HEkmDvsTH9Ut9l3_qHRpp00yRKZIk", + "items": [ + "AAAAAAAAAABRoiLHW7EFAB2lwAatTykipYZ3CZNPzLe-f5S-zUt8COtu0H12f_OZAwAFAAAAMpic85rur2MYf3zli8s8bHxTFjriFoMPTr6ZPs8sjxMKAAAAVBKuhU_hQmuvKlx88A5o-FH0rzNo59NsdxmOGNBQ-ycPAAAAMItdqgHZxf7j6l0oE8X-G9-VyMbnQmZrtSniuRe_EJ9CtyxsSb7daPIIYAaXMgSEsQ3dkxY5GjJjLwAAAAAAABqWlmx5B6wo0YWPIShNKmdVrAQWht2P85BS1drGLpkAAAAAADUJ-ARn7blgHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEIPAAAAAAAFAAAA-na5gFuxBQAFL-3CY4YuAJNGp9KhDkbrKkIPWYyq8WvtAaNPoUFWC16louSx8YN5", + "AAAAAAAAAAA0slHKW7EFAJNGp9KhDkbrKkIPWYyq8WvtAaNPoUFWC16louSx8YN5AwAFAAAAALcxv1ZiwwQ_QX9eOBZMbzIop6n7XtveS1FqOFwyvGMKAAAAC76ElC60qXSJQCHePpzzJxsCYvvrqvmkoHPyZnex-4QPAAAAKv0sz_rTANjoiJwMrdZFCJNFwdH0U_M5ouwMr3BXBfpCtyxsSb7daPIIYAaXMgSEsQ3dkxY5GjJjLwAAAAAAALJlIg1vY3w_9L63bePn1yk_5agvdEbIBBjm3adxc5xWAAAAAGzpBzdiVL9gHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQUIPAAAAAAAFAAAA-na5gFuxBQALiBhXgqaHAb4VWug3oddEVy0X9y_jEkE2Kmi_vyGP5ovr-fDIz_Uf" + ], + "limit": 2 + } + } + }, + "application/json;blockheader-encoding=object": { + "schema": { + "allOf": [ + { + "properties": { + "items": { + "description": "Array of JSON encoded block headers", + "items": { + "$ref": "#/components/schemas/blockHeader" + } + } + } + }, + { + "$ref": "#/components/schemas/page" + } + ] + }, + "example": { + "value": { + "next": "inclusive:o1S4NNFhKWg8T1HEkmDvsTH9Ut9l3_qHRpp00yRKZIk", + "items": [ + { + "creationTime": 1602382624629329, + "parent": "HaXABq1PKSKlhncJk0_Mt75_lL7NS3wI627QfXZ_85k", + "height": 1000000, + "hash": "k0an0qEORusqQg9ZjKrxa-0Bo0-hQVYLXqWi5LHxg3k", + "chainId": 0, + "weight": "NQn4BGftuWAeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "featureFlags": 0, + "epochStart": 1602381443331834, + "adjacents": { + "5": "Mpic85rur2MYf3zli8s8bHxTFjriFoMPTr6ZPs8sjxM", + "10": "VBKuhU_hQmuvKlx88A5o-FH0rzNo59NsdxmOGNBQ-yc", + "15": "MItdqgHZxf7j6l0oE8X-G9-VyMbnQmZrtSniuRe_EJ8" + }, + "payloadHash": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA", + "chainwebVersion": "mainnet01", + "target": "QrcsbEm-3WjyCGAGlzIEhLEN3ZMWORoyYy8AAAAAAAA", + "nonce": "13095611958898437" + }, + { + "creationTime": 1602382678045236, + "parent": "k0an0qEORusqQg9ZjKrxa-0Bo0-hQVYLXqWi5LHxg3k", + "height": 1000001, + "hash": "vhVa6Deh10RXLRf3L-MSQTYqaL-_IY_mi-v58MjP9R8", + "chainId": 0, + "weight": "bOkHN2JUv2AeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "featureFlags": 0, + "epochStart": 1602381443331834, + "adjacents": { + "5": "ALcxv1ZiwwQ_QX9eOBZMbzIop6n7XtveS1FqOFwyvGM", + "10": "C76ElC60qXSJQCHePpzzJxsCYvvrqvmkoHPyZnex-4Q", + "15": "Kv0sz_rTANjoiJwMrdZFCJNFwdH0U_M5ouwMr3BXBfo" + }, + "payloadHash": "smUiDW9jfD_0vrdt4-fXKT_lqC90RsgEGObdp3FznFY", + "chainwebVersion": "mainnet01", + "target": "QrcsbEm-3WjyCGAGlzIEhLEN3ZMWORoyYy8AAAAAAAA", + "nonce": "110239794631051275" + } + ], + "limit": 2 + } + } + } + } + }, + "404": { + "description": "The `next` or `maxheight` parameter indicated a nonexistent block height.\n", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "properties": { + "reason": { + "type": "string" + }, + "key": { + "$ref": "#/components/schemas/blockHash" + } + } + } + } + } + } + } + } + }, + "/chain/{chain}/header/{blockHash}": { + "get": { + "summary": "Get Block Header by Hash", + "description": "Query a block header by its hash", + "tags": [ + "header" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + }, + { + "$ref": "#/components/parameters/blockHash" + } + ], + "responses": { + "200": { + "description": "The block header with that hash was found", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/base64Header" + }, + "example": { + "value": { + "$ref": "#/components/examples/base64HeaderPage/value/items/0" + } + } + }, + "application/json;blockheader-encoding=object": { + "schema": { + "$ref": "#/components/schemas/blockHeader" + }, + "example": { + "value": { + "$ref": "#/components/examples/blockHeaderPage/value/items/0" + } + } + }, + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/binaryHeader" + } + } + } + }, + "404": { + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "description": "A block header with that block hash was not found.", + "content": { + "application/json": { + "schema": { + "properties": { + "reason": { + "type": "string" + }, + "key": { + "$ref": "#/components/schemas/blockHash" + } + } + } + } + } + }, + "406": { + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "description": "The value of the `Accept` header is not supported." + } + } + } + }, + "/chain/{chain}/header/branch": { + "post": { + "summary": "Get Block Header Branches", + "description": "A page of block headers from branches of the block chain in\n**descending** order.\n\nOnly blocks are returned that are ancestors of the some block in the\nset of upper bounds and are not ancestors of any block in the set of\nlower bounds.\n", + "tags": [ + "header" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + }, + { + "$ref": "#/components/parameters/limit" + }, + { + "$ref": "#/components/parameters/next" + }, + { + "$ref": "#/components/parameters/minheight" + }, + { + "$ref": "#/components/parameters/maxheight" + } + ], + "requestBody": { + "description": "Upper and lower bounds of the queried branches", + "content": { + "application/json": { + "schema": { + "properties": { + "lower": { + "description": "No blocks are returned that are predecessors of any block with\nan hash from this array.\n", + "type": "array", + "items": { + "$ref": "#/components/schemas/blockHash" + } + }, + "upper": { + "description": "Returned block headers are predecessors of a block with an\nhash from this array. This includes blocks with hashes from\nthis array.\n", + "type": "array", + "items": { + "$ref": "#/components/schemas/blockHash" + } + } + } + }, + "examples": { + "singletonLimited": { + "value": { + "lower": [ + "RClyuyZAacwvPpmLXKbTwrIRXWeUSjiNhJVP2esH8KM" + ], + "upper": [ + "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74" + ] + }, + "summary": "Ancestors of block that are not ancestors of another block" + }, + "singleton": { + "value": { + "lower": [], + "upper": [ + "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74" + ] + }, + "summary": "Ancestors of one block" + }, + "empty": { + "value": { + "lower": [], + "upper": [] + }, + "summary": "Empty branch" + }, + "empty2": { + "value": { + "lower": [ + "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74" + ], + "upper": [ + "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74" + ] + }, + "summary": "Another example that returns an empty page" + } + } + } + } + }, + "responses": { + "200": { + "description": "The block headers were found", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "properties": { + "items": { + "description": "Array of base64 encoded block headers", + "items": { + "$ref": "#/components/schemas/base64Header" + } + } + } + }, + { + "$ref": "#/components/schemas/page" + } + ] + }, + "example": { + "value": { + "next": "inclusive:u9Va7MRkDSOCm0yWpsC2w-4Z0oyEMv-BjofkHeIln6g", + "items": [ + "AAAAAAAAAADX5AyHgcAFAEQpcrsmQGnMLz6Zi1ym08KyEV1nlEo4jYSVT9nrB_CjAwAFAAAA4BMlW68KbggSREOGDeH_oFFoUrpZ0zX0hM0TTdYrEAYKAAAARoxLy8ECsIIWebtW8zZsH1xfRGu4NOuSlgH4cAJLFcwPAAAAsHRn1laXo2DK2_85nOH7apQyC6Vr_gEctSElqdrCC03a4wKcHiVawSuP3DULW8CnWwdh36wAF_eSBwAAAAAAAA3PRGZVm8h4aY9cMgXAQf3QbYSNDUnFxjZnr8FwcknXAAAAAIopfw9LdjBqowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3LgXAAAAAAAFAAAAavQWLYHABQAOBvq0L1PrvEMRggM-QGNWONZ4dclrYKoSoWfaT4j0WoBXSCjagR--", + "AAAAAAAAAAC46tSFgcAFANxrUMH15DY-83DeKwlvDWsj4DY4Sphc5I82jCVSpSuCAwAFAAAAwdorGxUmrIkWyssvz3oHm3uqurfNd5ywiD6NHsZQEr8KAAAA750C1IKC9doZZKtqCckOF8JmIaHMhDfopNobHeJvmXMPAAAA4pgr0U_1kQxou-NIc42nICYqOgLM1Vawamal-HuhLvfa4wKcHiVawSuP3DULW8CnWwdh36wAF_eSBwAAAAAAANdqRLGXd6y6OGwShrFC7vBrIWf_TLCfaYpLnu-q7A7AAAAAAI5IadugqQ5qowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA27gXAAAAAAAFAAAAavQWLYHABQBFGVPEmhORyEQpcrsmQGnMLz6Zi1ym08KyEV1nlEo4jYSVT9nrB_Cj" + ], + "limit": 2 + } + } + }, + "application/json;blockheader-encoding=object": { + "schema": { + "allOf": [ + { + "properties": { + "items": { + "description": "Array of JSON encoded block headers", + "items": { + "$ref": "#/components/schemas/blockHeader" + } + } + } + }, + { + "$ref": "#/components/schemas/page" + } + ] + }, + "example": { + "value": { + "next": "inclusive:3GtQwfXkNj7zcN4rCW8NayPgNjhKmFzkjzaMJVKlK4I", + "items": [ + { + "creationTime": 1619037432636631, + "parent": "RClyuyZAacwvPpmLXKbTwrIRXWeUSjiNhJVP2esH8KM", + "height": 1554652, + "hash": "QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH74", + "chainId": 0, + "weight": "iil_D0t2MGqjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "featureFlags": 0, + "epochStart": 1619035923346538, + "adjacents": { + "5": "4BMlW68KbggSREOGDeH_oFFoUrpZ0zX0hM0TTdYrEAY", + "10": "RoxLy8ECsIIWebtW8zZsH1xfRGu4NOuSlgH4cAJLFcw", + "15": "sHRn1laXo2DK2_85nOH7apQyC6Vr_gEctSElqdrCC00" + }, + "payloadHash": "Dc9EZlWbyHhpj1wyBcBB_dBthI0NScXGNmevwXBySdc", + "chainwebVersion": "mainnet01", + "target": "2uMCnB4lWsErj9w1C1vAp1sHYd-sABf3kgcAAAAAAAA", + "nonce": "13613065763022308878" + }, + { + "creationTime": 1619037412190904, + "parent": "3GtQwfXkNj7zcN4rCW8NayPgNjhKmFzkjzaMJVKlK4I", + "height": 1554651, + "hash": "RClyuyZAacwvPpmLXKbTwrIRXWeUSjiNhJVP2esH8KM", + "chainId": 0, + "weight": "jkhp26CpDmqjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "featureFlags": 0, + "epochStart": 1619035923346538, + "adjacents": { + "5": "wdorGxUmrIkWyssvz3oHm3uqurfNd5ywiD6NHsZQEr8", + "10": "750C1IKC9doZZKtqCckOF8JmIaHMhDfopNobHeJvmXM", + "15": "4pgr0U_1kQxou-NIc42nICYqOgLM1Vawamal-HuhLvc" + }, + "payloadHash": "12pEsZd3rLo4bBKGsULu8GshZ_9MsJ9pikue76rsDsA", + "chainwebVersion": "mainnet01", + "target": "2uMCnB4lWsErj9w1C1vAp1sHYd-sABf3kgcAAAAAAAA", + "nonce": "14452354234648303941" + } + ], + "limit": 2 + } + } + } + } + }, + "404": { + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "description": "A block header indicated by a required parameter was not found.", + "content": { + "application/json": { + "schema": { + "properties": { + "reason": { + "type": "string" + }, + "key": { + "$ref": "#/components/schemas/blockHash" + } + } + } + } + } + }, + "406": { + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "description": "The value of the `Accept` header is not supported." + } + } + } + }, + "/chain/{chain}/payload/{payloadHash}": { + "get": { + "summary": "Get Block Payload", + "tags": [ + "payload" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + }, + { + "$ref": "#/components/parameters/payloadHash" + } + ], + "responses": { + "200": { + "description": "The payload data of for the given block payload hash", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/payload" + }, + "examples": { + "payload": { + "summary": "Payload with one transaction", + "value": { + "transactions": [ + "eyJoYXNoIjoiMi16Q3dmRFZZR010WHljd2pTLXRlNzh5U3l3T3JXcjNSdUhiQlJnNDdhRSIsInNpZ3MiOlt7InNpZyI6ImZiMTVkNzkyYTNkNDM1MDI5ODJmOGQ1MGUyMzA1NTI5OWEwZjdhMWRmMWE4YjUyMmE5NTMxNWUyZDljY2MyNmE1MzI4M2I5YTNhNDM5ZWE0ZGY4MGM1ZTIwMjg4NDhjNjFhMWY0MGM5OWIyOTYzOWM0NGNkYTgwMzBmYmViYjBjIn1dLCJjbWQiOiJ7XCJuZXR3b3JrSWRcIjpcIm1haW5uZXQwMVwiLFwicGF5bG9hZFwiOntcImV4ZWNcIjp7XCJkYXRhXCI6e30sXCJjb2RlXCI6XCIoY29pbi50cmFuc2ZlciBcXFwiZTc1NzU4ZGQyYTFjNTk2NDRjMjJlMDQyYzZlYzA3NTI2ZWE0ZTU3MTU0ZjlkYmMyMDc2ZThhODRhYzE5NGYzMlxcXCIgXFxcIjQ2NzdhMDllYTE2MDJlNGUwOWZlMDFlYjExOTZjZjQ3YzBmNDRhYTQ0YWFjOTAzZDVmNjFiZTdkYTM0MjUxMjhcXFwiIDMuNzc2KVwifX0sXCJzaWduZXJzXCI6W3tcInB1YktleVwiOlwiZTc1NzU4ZGQyYTFjNTk2NDRjMjJlMDQyYzZlYzA3NTI2ZWE0ZTU3MTU0ZjlkYmMyMDc2ZThhODRhYzE5NGYzMlwiLFwiY2xpc3RcIjpbe1wiYXJnc1wiOltdLFwibmFtZVwiOlwiY29pbi5HQVNcIn0se1wiYXJnc1wiOltcImU3NTc1OGRkMmExYzU5NjQ0YzIyZTA0MmM2ZWMwNzUyNmVhNGU1NzE1NGY5ZGJjMjA3NmU4YTg0YWMxOTRmMzJcIixcIjQ2NzdhMDllYTE2MDJlNGUwOWZlMDFlYjExOTZjZjQ3YzBmNDRhYTQ0YWFjOTAzZDVmNjFiZTdkYTM0MjUxMjhcIiwzLjc3Nl0sXCJuYW1lXCI6XCJjb2luLlRSQU5TRkVSXCJ9XX1dLFwibWV0YVwiOntcImNyZWF0aW9uVGltZVwiOjE2MDIzODI4MTQsXCJ0dGxcIjoyODgwMCxcImdhc0xpbWl0XCI6NjAwLFwiY2hhaW5JZFwiOlwiMFwiLFwiZ2FzUHJpY2VcIjoxLjBlLTUsXCJzZW5kZXJcIjpcImU3NTc1OGRkMmExYzU5NjQ0YzIyZTA0MmM2ZWMwNzUyNmVhNGU1NzE1NGY5ZGJjMjA3NmU4YTg0YWMxOTRmMzJcIn0sXCJub25jZVwiOlwiXFxcIjIwMjAtMTAtMTFUMDI6MjE6MTQuMTk0WlxcXCJcIn0ifQ" + ], + "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + "transactionsHash": "lWcQRlj3MV7FSem8P4G-8GMRf1-O7zQqi_AwmWnk-N0", + "outputsHash": "9BzXZbhjSSevp4K0bYFqi1GdLjeX_DB-4u1T5Em8abs", + "payloadHash": "jcQOWz7K9qKnkUv4Z883D2ZjkFFGgccoSroWGaoogLM" + } + }, + "emptyPayload": { + "summary": "Empty block payload", + "value": { + "transactions": [], + "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + "transactionsHash": "nT0j4xw2woMkdXXaopdurXIn24OG-jNMqQzUGfxV_MA", + "outputsHash": "4pXRrZ2K0_V0iGAxQCKrKdLjQTBZHBOQS7P-47kdnhY", + "payloadHash": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA" + } + } + } + } + } + }, + "404": { + "description": "The block payload with that hash was not found", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "properties": { + "reason": { + "type": "string", + "description": "Failure message" + }, + "key": { + "$ref": "#/components/schemas/payloadHash" + } + } + }, + "example": { + "reason": "key not found", + "key": "k1H3DsInAPvJ0W_zPxnrpkeSNdPUT0S9U8bqDLG739w" + } + } + } + } + } + } + }, + "/chain/{chain}/payload/batch": { + "post": { + "summary": "Get Batch of Block Payload", + "tags": [ + "payload" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + } + ], + "requestBody": { + "$ref": "#/components/requestBodies/payloadHashArray" + }, + "responses": { + "200": { + "description": "Array of the some or all of the requested block payloads. The\npayloads may be returned in any order.\n", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/payload" + } + }, + "examples": { + "two": { + "value": { + "value": [ + { + "transactions": [], + "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + "transactionsHash": "nT0j4xw2woMkdXXaopdurXIn24OG-jNMqQzUGfxV_MA", + "outputsHash": "4pXRrZ2K0_V0iGAxQCKrKdLjQTBZHBOQS7P-47kdnhY", + "payloadHash": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA" + }, + { + "transactions": [ + "eyJoYXNoIjoiMi16Q3dmRFZZR010WHljd2pTLXRlNzh5U3l3T3JXcjNSdUhiQlJnNDdhRSIsInNpZ3MiOlt7InNpZyI6ImZiMTVkNzkyYTNkNDM1MDI5ODJmOGQ1MGUyMzA1NTI5OWEwZjdhMWRmMWE4YjUyMmE5NTMxNWUyZDljY2MyNmE1MzI4M2I5YTNhNDM5ZWE0ZGY4MGM1ZTIwMjg4NDhjNjFhMWY0MGM5OWIyOTYzOWM0NGNkYTgwMzBmYmViYjBjIn1dLCJjbWQiOiJ7XCJuZXR3b3JrSWRcIjpcIm1haW5uZXQwMVwiLFwicGF5bG9hZFwiOntcImV4ZWNcIjp7XCJkYXRhXCI6e30sXCJjb2RlXCI6XCIoY29pbi50cmFuc2ZlciBcXFwiZTc1NzU4ZGQyYTFjNTk2NDRjMjJlMDQyYzZlYzA3NTI2ZWE0ZTU3MTU0ZjlkYmMyMDc2ZThhODRhYzE5NGYzMlxcXCIgXFxcIjQ2NzdhMDllYTE2MDJlNGUwOWZlMDFlYjExOTZjZjQ3YzBmNDRhYTQ0YWFjOTAzZDVmNjFiZTdkYTM0MjUxMjhcXFwiIDMuNzc2KVwifX0sXCJzaWduZXJzXCI6W3tcInB1YktleVwiOlwiZTc1NzU4ZGQyYTFjNTk2NDRjMjJlMDQyYzZlYzA3NTI2ZWE0ZTU3MTU0ZjlkYmMyMDc2ZThhODRhYzE5NGYzMlwiLFwiY2xpc3RcIjpbe1wiYXJnc1wiOltdLFwibmFtZVwiOlwiY29pbi5HQVNcIn0se1wiYXJnc1wiOltcImU3NTc1OGRkMmExYzU5NjQ0YzIyZTA0MmM2ZWMwNzUyNmVhNGU1NzE1NGY5ZGJjMjA3NmU4YTg0YWMxOTRmMzJcIixcIjQ2NzdhMDllYTE2MDJlNGUwOWZlMDFlYjExOTZjZjQ3YzBmNDRhYTQ0YWFjOTAzZDVmNjFiZTdkYTM0MjUxMjhcIiwzLjc3Nl0sXCJuYW1lXCI6XCJjb2luLlRSQU5TRkVSXCJ9XX1dLFwibWV0YVwiOntcImNyZWF0aW9uVGltZVwiOjE2MDIzODI4MTQsXCJ0dGxcIjoyODgwMCxcImdhc0xpbWl0XCI6NjAwLFwiY2hhaW5JZFwiOlwiMFwiLFwiZ2FzUHJpY2VcIjoxLjBlLTUsXCJzZW5kZXJcIjpcImU3NTc1OGRkMmExYzU5NjQ0YzIyZTA0MmM2ZWMwNzUyNmVhNGU1NzE1NGY5ZGJjMjA3NmU4YTg0YWMxOTRmMzJcIn0sXCJub25jZVwiOlwiXFxcIjIwMjAtMTAtMTFUMDI6MjE6MTQuMTk0WlxcXCJcIn0ifQ" + ], + "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + "transactionsHash": "lWcQRlj3MV7FSem8P4G-8GMRf1-O7zQqi_AwmWnk-N0", + "outputsHash": "9BzXZbhjSSevp4K0bYFqi1GdLjeX_DB-4u1T5Em8abs", + "payloadHash": "jcQOWz7K9qKnkUv4Z883D2ZjkFFGgccoSroWGaoogLM" + } + ] + }, + "summary": "Result with two payloads" + }, + "empty": { + "value": [], + "summary": "Empty result" + } + } + } + } + } + } + } + }, + "/chain/{chain}/payload/{payloadHash}/outputs": { + "get": { + "summary": "Get Block Payload With Outputs", + "tags": [ + "payload" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + }, + { + "$ref": "#/components/parameters/payloadHash" + } + ], + "responses": { + "200": { + "description": "The payload with outputs for the given block payload hash", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/payloadWithOutputs" + }, + "examples": { + "payload": { + "summary": "Payload with outputs with one transaction", + "value": { + "value": { + "transactions": [ + [ + "eyJoYXNoIjoiMi16Q3dmRFZZR010WHljd2pTLXRlNzh5U3l3T3JXcjNSdUhiQlJnNDdhRSIsInNpZ3MiOlt7InNpZyI6ImZiMTVkNzkyYTNkNDM1MDI5ODJmOGQ1MGUyMzA1NTI5OWEwZjdhMWRmMWE4YjUyMmE5NTMxNWUyZDljY2MyNmE1MzI4M2I5YTNhNDM5ZWE0ZGY4MGM1ZTIwMjg4NDhjNjFhMWY0MGM5OWIyOTYzOWM0NGNkYTgwMzBmYmViYjBjIn1dLCJjbWQiOiJ7XCJuZXR3b3JrSWRcIjpcIm1haW5uZXQwMVwiLFwicGF5bG9hZFwiOntcImV4ZWNcIjp7XCJkYXRhXCI6e30sXCJjb2RlXCI6XCIoY29pbi50cmFuc2ZlciBcXFwiZTc1NzU4ZGQyYTFjNTk2NDRjMjJlMDQyYzZlYzA3NTI2ZWE0ZTU3MTU0ZjlkYmMyMDc2ZThhODRhYzE5NGYzMlxcXCIgXFxcIjQ2NzdhMDllYTE2MDJlNGUwOWZlMDFlYjExOTZjZjQ3YzBmNDRhYTQ0YWFjOTAzZDVmNjFiZTdkYTM0MjUxMjhcXFwiIDMuNzc2KVwifX0sXCJzaWduZXJzXCI6W3tcInB1YktleVwiOlwiZTc1NzU4ZGQyYTFjNTk2NDRjMjJlMDQyYzZlYzA3NTI2ZWE0ZTU3MTU0ZjlkYmMyMDc2ZThhODRhYzE5NGYzMlwiLFwiY2xpc3RcIjpbe1wiYXJnc1wiOltdLFwibmFtZVwiOlwiY29pbi5HQVNcIn0se1wiYXJnc1wiOltcImU3NTc1OGRkMmExYzU5NjQ0YzIyZTA0MmM2ZWMwNzUyNmVhNGU1NzE1NGY5ZGJjMjA3NmU4YTg0YWMxOTRmMzJcIixcIjQ2NzdhMDllYTE2MDJlNGUwOWZlMDFlYjExOTZjZjQ3YzBmNDRhYTQ0YWFjOTAzZDVmNjFiZTdkYTM0MjUxMjhcIiwzLjc3Nl0sXCJuYW1lXCI6XCJjb2luLlRSQU5TRkVSXCJ9XX1dLFwibWV0YVwiOntcImNyZWF0aW9uVGltZVwiOjE2MDIzODI4MTQsXCJ0dGxcIjoyODgwMCxcImdhc0xpbWl0XCI6NjAwLFwiY2hhaW5JZFwiOlwiMFwiLFwiZ2FzUHJpY2VcIjoxLjBlLTUsXCJzZW5kZXJcIjpcImU3NTc1OGRkMmExYzU5NjQ0YzIyZTA0MmM2ZWMwNzUyNmVhNGU1NzE1NGY5ZGJjMjA3NmU4YTg0YWMxOTRmMzJcIn0sXCJub25jZVwiOlwiXFxcIjIwMjAtMTAtMTFUMDI6MjE6MTQuMTk0WlxcXCJcIn0ifQ", + "eyJnYXMiOjU3MiwicmVzdWx0Ijp7InN0YXR1cyI6InN1Y2Nlc3MiLCJkYXRhIjoiV3JpdGUgc3VjY2VlZGVkIn0sInJlcUtleSI6IjItekN3ZkRWWUdNdFh5Y3dqUy10ZTc4eVN5d09yV3IzUnVIYkJSZzQ3YUUiLCJsb2dzIjoiSU1ra1VFZmVGak45bFQxZ0gtX2ZNT1dDRklrU1d6aVNTZHF2eEo4dS16RSIsIm1ldGFEYXRhIjpudWxsLCJjb250aW51YXRpb24iOm51bGwsInR4SWQiOjEyNzIzNzJ9" + ] + ], + "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + "transactionsHash": "lWcQRlj3MV7FSem8P4G-8GMRf1-O7zQqi_AwmWnk-N0", + "outputsHash": "9BzXZbhjSSevp4K0bYFqi1GdLjeX_DB-4u1T5Em8abs", + "payloadHash": "jcQOWz7K9qKnkUv4Z883D2ZjkFFGgccoSroWGaoogLM", + "coinbase": "eyJnYXMiOjAsInJlc3VsdCI6eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6IldyaXRlIHN1Y2NlZWRlZCJ9LCJyZXFLZXkiOiJJbkV4WDFkUk16SnliRmhCWW1KcU9WTnZkMXB2YmtabmNHRXdlRnBXUWtKdmNUWTJiRk0xY0RSQ1ZVVWkiLCJsb2dzIjoiSVc0N0QxTXFMVW9mRnNKbWpoWGdDZnhnb2Fzb0xTc05YZUFiOFRPb2NCNCIsIm1ldGFEYXRhIjpudWxsLCJjb250aW51YXRpb24iOm51bGwsInR4SWQiOjEyNzIzNzB9" + } + } + }, + "emptyPayload": { + "summary": "Empty block payload", + "value": { + "value": { + "transactions": [], + "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + "transactionsHash": "nT0j4xw2woMkdXXaopdurXIn24OG-jNMqQzUGfxV_MA", + "outputsHash": "4pXRrZ2K0_V0iGAxQCKrKdLjQTBZHBOQS7P-47kdnhY", + "payloadHash": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA", + "coinbase": "eyJnYXMiOjAsInJlc3VsdCI6eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6IldyaXRlIHN1Y2NlZWRlZCJ9LCJyZXFLZXkiOiJJa2hoV0VGQ2NURlFTMU5MYkdodVkwcHJNRjlOZERjMVgyeE1OMDVUTTNkSk5qSTNVV1pZV2w4NE5Xc2kiLCJsb2dzIjoiZ3Noak1kWFJrVGxKYmIxalZkQWJ6SVVDcGpQb1JBQ2pEbExzRzBXNkJEMCIsIm1ldGFEYXRhIjpudWxsLCJjb250aW51YXRpb24iOm51bGwsInR4SWQiOjEyNzIzNTB9" + } + } + } + } + } + } + }, + "404": { + "description": "A block payload with that hash was not found", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "properties": { + "reason": { + "type": "string", + "description": "Failure message" + }, + "key": { + "$ref": "#/components/schemas/payloadHash" + } + } + }, + "example": { + "reason": "key not found", + "key": "k1H3DsInAPvJ0W_zPxnrpkeSNdPUT0S9U8bqDLG739w" + } + } + } + } + } + } + }, + "/chain/{chain}/payload/outputs/batch": { + "post": { + "summary": "Get Batch of Block Payload With Outputs", + "tags": [ + "payload" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + } + ], + "requestBody": { + "$ref": "#/components/requestBodies/payloadHashArray" + }, + "responses": { + "200": { + "description": "Array of the some or all of the requested block payloads with\noutputs. Result items maybe returned in any order.\n", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/payloadWithOutputs" + } + }, + "examples": { + "two": { + "value": { + "value": [ + { + "$ref": "#/components/examples/emptyPayload" + }, + { + "$ref": "#/components/examples/payloadWithTransactions" + } + ] + }, + "summary": "Result with two payloads" + }, + "empty": { + "value": [], + "summary": "Empty result" + } + } + } + } + } + } + } + }, + "/chain/{chain}/mempool/getPending": { + "post": { + "summary": "Get Pending Transactions from the Mempool", + "tags": [ + "mempool" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + }, + { + "name": "nonce", + "in": "query", + "description": "Server nonce value", + "schema": { + "type": "integer" + } + }, + { + "name": "since", + "in": "query", + "description": "Mempool tx id value", + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "recent state of pending transactions in the mempool", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "properties": { + "hashes": { + "type": "array", + "items": { + "type": "string" + } + }, + "highwaterMark": { + "type": "array", + "description": "two-element array: `[nonce (integer), since (int64)]`", + "items": { + "type": "integer" + } + } + } + }, + "examples": { + "singleton": { + "value": { + "hashes": [ + "qx346ILpakzgbNZbE8oHqF5TZQghp-HPcV-0Ptc_n2s" + ], + "highwaterMark": [ + 7530864100535969000, + 399 + ] + }, + "summary": "Result with one transaction" + }, + "empty": { + "value": { + "hashes": [], + "highwaterMark": [ + -4683248684880063000, + 436 + ] + }, + "summary": "Empty result" + } + } + } + } + } + } + } + }, + "/chain/{chain}/mempool/member": { + "post": { + "summary": "Check for Pending Transactions in the Mempool", + "tags": [ + "mempool" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + } + ], + "requestBody": { + "$ref": "#/components/requestBodies/requestKeyArray" + }, + "responses": { + "200": { + "description": "Array of boolean values that indicate whether the respective\ntransaction is in the mempool.\n\nThe array has the same size as the request body.\n", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "boolean" + } + }, + "examples": { + "hit": { + "value": [ + true + ], + "summary": "result for existing transaction" + }, + "miss": { + "value": [ + false + ], + "summary": "result for missing transaction" + }, + "empty": { + "value": [], + "summary": "result from empty request body" + } + } + } + } + } + } + } + }, + "/chain/{chain}/mempool/lookup": { + "post": { + "summary": "Lookup Pending Transactions in the Mempool", + "tags": [ + "mempool" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + } + ], + "requestBody": { + "$ref": "#/components/requestBodies/requestKeyArray" + }, + "responses": { + "200": { + "description": "Array of lookup results for the respective transactions\n", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "tag": { + "type": "string", + "enum": [ + "Missing", + "Pending" + ] + }, + "contents": { + "$ref": "#/components/schemas/signedTxText" + } + } + } + }, + "examples": { + "hit": { + "value": [ + { + "tag": "Pending", + "contents": "{\"hash\":\"y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw\",\"sigs\":[{\"sig\":\"8ddc06b37c496f2cadc4f7412405a80faf3ab07482ff5553b9b5fcc73d1b4121275ad5948d9b4078e553b71f8b42eaf6b24135bf2fb4d5840c16bcdde0e35e0f\"}],\"cmd\":\"{\\\"networkId\\\":\\\"mainnet01\\\",\\\"payload\\\":{\\\"exec\\\":{\\\"data\\\":{\\\"account-keyset\\\":{\\\"pred\\\":\\\"keys-all\\\",\\\"keys\\\":[\\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\"]}},\\\"code\\\":\\\"(coin.transfer-create \\\\\\\"60241f51ea34e05c61fbea9d\\\\\\\" \\\\\\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\\\\\" (read-keyset \\\\\\\"account-keyset\\\\\\\") 5007.0000)\\\"}},\\\"signers\\\":[{\\\"pubKey\\\":\\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\",\\\"clist\\\":[{\\\"args\\\":[\\\"60241f51ea34e05c61fbea9d\\\",\\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\",5007],\\\"name\\\":\\\"coin.TRANSFER\\\"},{\\\"args\\\":[],\\\"name\\\":\\\"coin.GAS\\\"}]}],\\\"meta\\\":{\\\"creationTime\\\":1618949714,\\\"ttl\\\":300,\\\"gasLimit\\\":600,\\\"chainId\\\":\\\"0\\\",\\\"gasPrice\\\":1.0e-7,\\\"sender\\\":\\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\"},\\\"nonce\\\":\\\"\\\\\\\"2021-04-20T20:16:13.645Z\\\\\\\"\\\"}\"}" + } + ], + "summary": "result for existing transaction" + }, + "miss": { + "value": [ + { + "tag": "Missing" + } + ], + "summary": "result for missing transaction" + }, + "empty": { + "value": [], + "summary": "result from empty request body" + } + } + } + } + } + } + } + }, + "/chain/{chain}/mempool/insert": { + "put": { + "summary": "Insert Transactions into the Mempool", + "tags": [ + "mempool" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + } + ], + "requestBody": { + "description": "Array of strings of JSON encoded signed transactions", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/signedTxText" + } + }, + "examples": { + "singleton": { + "summary": "Singleton request body", + "value": [ + "{\"hash\":\"y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw\",\"sigs\":[{\"sig\":\"8ddc06b37c496f2cadc4f7412405a80faf3ab07482ff5553b9b5fcc73d1b4121275ad5948d9b4078e553b71f8b42eaf6b24135bf2fb4d5840c16bcdde0e35e0f\"}],\"cmd\":\"{\\\"networkId\\\":\\\"mainnet01\\\",\\\"payload\\\":{\\\"exec\\\":{\\\"data\\\":{\\\"account-keyset\\\":{\\\"pred\\\":\\\"keys-all\\\",\\\"keys\\\":[\\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\"]}},\\\"code\\\":\\\"(coin.transfer-create \\\\\\\"60241f51ea34e05c61fbea9d\\\\\\\" \\\\\\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\\\\\" (read-keyset \\\\\\\"account-keyset\\\\\\\") 5007.0000)\\\"}},\\\"signers\\\":[{\\\"pubKey\\\":\\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\",\\\"clist\\\":[{\\\"args\\\":[\\\"60241f51ea34e05c61fbea9d\\\",\\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\",5007],\\\"name\\\":\\\"coin.TRANSFER\\\"},{\\\"args\\\":[],\\\"name\\\":\\\"coin.GAS\\\"}]}],\\\"meta\\\":{\\\"creationTime\\\":1618949714,\\\"ttl\\\":300,\\\"gasLimit\\\":600,\\\"chainId\\\":\\\"0\\\",\\\"gasPrice\\\":1.0e-7,\\\"sender\\\":\\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\"},\\\"nonce\\\":\\\"\\\\\\\"2021-04-20T20:16:13.645Z\\\\\\\"\\\"}\"}" + ] + }, + "empty": { + "summary": "Empty request body", + "value": [] + } + } + } + } + }, + "responses": { + "200": { + "description": "Transactions were inserted", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + } + } + } + } + }, + "/chain/{chain}/mempool/peer": { + "get": { + "summary": "Get Chain Mempool-Network Peer Info", + "tags": [ + "peer" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + }, + { + "$ref": "#/components/parameters/limit" + }, + { + "$ref": "#/components/parameters/next" + } + ], + "responses": { + "200": { + "description": "Peer information", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "description": "Peers from the peer database of the remote node", + "allOf": [ + { + "properties": { + "items": { + "description": "Array of peers", + "items": { + "$ref": "#/components/schemas/peer" + } + } + } + }, + { + "$ref": "#/components/schemas/page" + } + ] + }, + "example": { + "value": { + "next": "inclusive:3", + "items": [ + { + "address": { + "hostname": "85.238.99.91", + "port": 30004 + }, + "id": "PRLmVUcc9AH3fyfMYiWeC4nV2i1iHwc0-aM7iAO8h18" + }, + { + "address": { + "hostname": "us-w3.chainweb.com", + "port": 443 + }, + "id": null + }, + { + "address": { + "hostname": "95.111.232.151", + "port": 30004 + }, + "id": "DguFKLFMxp12vfl1z3cQIJQlh8xOpeZuBkpJU9Y-VLo" + } + ], + "limit": 3 + } + } + } + } + } + } + }, + "put": { + "summary": "Put Chain Mempool-Network Peer Info", + "tags": [ + "peer" + ], + "parameters": [ + { + "$ref": "#/components/parameters/chain" + } + ], + "requestBody": { + "description": "The peer that is added to the peer database of the mempoo P2P network of\nthe chain `{chain}` of remote host.\n", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/peer" + }, + { + "properties": { + "id": { + "nullable": true + } + } + } + ] + } + } + } + }, + "responses": { + "204": { + "description": "The peer got added to the peer database of the remote node.", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + } + }, + "400": { + "description": "Bad Request.\nThe request is invalid. It is either malformed or the provided peer is not reachable.\n\nBefore the remote node addes a peer to its peer database it checks whether the peer can be reached\nvia the provided address. If this check fails an error is returned.\n", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "text/plain": { + "description": "The reason for the failure.", + "example": "Invalid hostaddress: IsNotReachable (PeerInfo {_peerId = Nothing, _peerAddr = HostAddress {_hostAddressHost = us-w1.chainweb.com, _hostAddressPort = 444}}) \"\\\"HttpExceptionRequest Request {\\\\n host = \\\\\\\"us-w1.chainweb.com\\\\\\\"\\\\n port = 444\\\\n secure = True\\\\n requestHeaders = [(\\\\\\\"X-Chainweb-Node-Version\\\\\\\",\\\\\\\"2.6\\\\\\\")]\\\\n path = \\\\\\\"/chainweb/0.0/mainnet01/cut/peer\\\\\\\"\\\\n queryString = \\\\\\\"\\\\\\\"\\\\n method = \\\\\\\"GET\\\\\\\"\\\\n proxy = Nothing\\\\n rawBody = False\\\\n redirectCount = 10\\\\n responseTimeout = ResponseTimeoutMicro 2000000\\\\n requestVersion = HTTP/1.1\\\\n}\\\\n ConnectionTimeout\\\"\"" + } + } + } + } + } + }, + "/mining/work": { + "servers": [ + { + "url": "{schema}://{domain}:{port}/chainweb/{chainwebVersion}/{apiVersion}", + "description": "The service API port of a chainweb-node where the mining API is enabled\nand that is configured for mining.\n", + "variables": { + "schema": { + "default": "http", + "enum": [ + "http", + "https" + ] + }, + "domain": { + "default": "example.com" + }, + "port": { + "default": "1848" + }, + "chainwebVersion": { + "default": "mainnet01", + "enum": [ + "test-singleton", + "development", + "mainnet01", + "testnet04" + ] + }, + "apiVersion": { + "default": "0.0" + } + } + } + ], + "get": { + "tags": [ + "mining" + ], + "summary": "Get Mining Work", + "description": "A new BlockHeader to mine on", + "requestBody": { + "description": "Miner Info", + "content": { + "application/json": { + "example": { + "account": "miner", + "predicate": "keys-all", + "public-keys": [ + "f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27" + ] + }, + "schema": { + "$ref": "#/components/schemas/minerInfo" + } + } + } + }, + "responses": { + "200": { + "description": "A mining work item", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/octet-stream": { + "schema": { + "title": "322 Work Bytes", + "description": "The first 36 bytes are informational. Only the bytes from\nposition 36 to the end are subject of the POW hash\ncomputation.\n", + "properties": { + "chainBytes": { + "title": "4 Chain ID Bytes", + "description": "The chain selection made by the Node. This is\ninformational. Generally, miner should not care about the\nchain.\n", + "type": "string", + "format": "binary" + }, + "targetBytes": { + "title": "32 PoW Target Bytes", + "description": "The PoW target for the current block. The PoW hash of a\nvalid block must not be larger than this value.\n\nFor arithmetic comparisons the hash-target and the PoW\nhash are interpreted as unsigned 256 bit integral number\nin little endian encoding.\n", + "type": "string", + "format": "binary" + }, + "headerBytes": { + "title": "286 Work Header Bytes", + "description": "PoW Work Header Bytes. The last 8 bytes are the nonce. The\ncreation time is encoded in bytes 44-52. Miners must not\nchange or make any assumption about the other bytes.\n\nThe creation time is encoded as little endian twoth\ncomplement integral number that counts SI microseconds\nsince POSIX epoch (leap seconds are ignored). It always\npositive (highest bit is 0). Miners are free but not\nrequired to update the creation time. The value must be\nstrictly larger than the creation time of the parent block\nand must not be in the future.\n", + "type": "string", + "format": "binary" + } + } + } + } + } + } + } + } + }, + "/chainweb/0.0/mainnet01/mining/solved": { + "servers": [ + { + "url": "{schema}://{domain}:{port}/chainweb/{chainwebVersion}/{apiVersion}", + "description": "The service API port of a chainweb-node where the mining API is enabled\nand that is configured for mining.\n", + "variables": { + "schema": { + "default": "http", + "enum": [ + "http", + "https" + ] + }, + "domain": { + "default": "example.com" + }, + "port": { + "default": "1848" + }, + "chainwebVersion": { + "default": "mainnet01", + "enum": [ + "test-singleton", + "development", + "mainnet01", + "testnet04" + ] + }, + "apiVersion": { + "default": "0.0" + } + } + } + ], + "post": { + "tags": [ + "mining" + ], + "summary": "Solved Mining Work", + "description": "Submit a solution for a new block", + "requestBody": { + "description": "The solved PoW work header bytes", + "content": { + "application/octet-stream": { + "schema": { + "title": "286 Solved PoW Work Header Bytes", + "description": "The original work received that was received from `/mining/work`\nwith updated nonce value such that it satisfies the\nProof-of-Work. The nonce are last 8 bytes of the work header\nbytes.\n\nThe PoW hash of a valid block is computed using `blake2s`. It\nmust not be larger than the PoW target for the current block.\nThe target was received along with the work header bytes from\nthe `/mining/work` endpoint. For arithmetic comparisons the\nhash-target and the PoW hash are interpreted as unsigned 256 bit\nintegral number in little endian encoding.\n\nMiners are free but not required to also update the creation time.\nThe value must be strictly larger than the creation time of the\nparent block and must not be in the future.\n", + "type": "string", + "format": "binary" + } + } + } + }, + "responses": { + "204": { + "description": "Solved mining work is valid", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + } + } + } + } + }, + "/mining/updates": { + "servers": [ + { + "url": "{schema}://{domain}:{port}/chainweb/{chainwebVersion}/{apiVersion}", + "description": "The service API port of a chainweb-node where the mining API is enabled\nand that is configured for mining.\n", + "variables": { + "schema": { + "default": "http", + "enum": [ + "http", + "https" + ] + }, + "domain": { + "default": "example.com" + }, + "port": { + "default": "1848" + }, + "chainwebVersion": { + "default": "mainnet01", + "enum": [ + "test-singleton", + "development", + "mainnet01", + "testnet04" + ] + }, + "apiVersion": { + "default": "0.0" + } + } + } + ], + "get": { + "tags": [ + "mining" + ], + "summary": "Notification of Updated Work", + "description": "An server-sent event sources that notifies miners when new mining\nwork becomes available.\n\nThe stream is terminated by the server in regular intervals and\nit is up to the client to request a new stream.\n", + "requestBody": { + "description": "The first 4 bytes received from a call to `/mining/work`. This tells the Node to only inform the Miner of a new Cut when the specific chain in question has updated.", + "content": { + "application/octet-stream": { + "schema": { + "title": "4 Chain ID bytes", + "type": "string", + "format": "binary" + } + } + } + }, + "responses": { + "200": { + "description": "Each events consists of a single line: `event:New Cut`.\nEvents are separated by empty lines.\n", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "text/event-stream": { + "schema": { + "$ref": "#/components/schemas/miningUpdateEventStream" + }, + "example": "event:New Cut\n\nevent:New Cut\n\nevent:New Cut\n" + } + } + } + } + } + }, + "/config": { + "get": { + "tags": [ + "config", + "misc" + ], + "summary": "Configuration of Chainweb Node", + "description": "Returns the configuration of chainweb-node as a JSON structure.\nSensitive information is removed from the result. The JSON schema depends\non the chainweb node version and is not part of the stable chainweb-node\nAPI.\n", + "responses": { + "200": { + "description": "Configuration of the chainweb node", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "example": { + "value": { + "allowReadsInLocal": false, + "rosetta": true, + "throttling": { + "local": 1, + "mining": 2, + "global": 200, + "putPeer": 21 + }, + "serviceApi": { + "interface": "invalid", + "port": 0 + }, + "validateHashesOnReplay": false, + "chainwebVersion": "mainnet01", + "pactQueueSize": 2000, + "mining": { + "coordination": { + "enabled": false, + "updateStreamTimeout": 240, + "limit": 1200, + "updateStreamLimit": 2000, + "miners": [] + }, + "nodeMining": { + "miner": { + "account": "", + "predicate": "keys-all", + "public-keys": [] + }, + "enabled": false + } + }, + "p2p": { + "peer": { + "certificateChainFile": null, + "key": null, + "interface": "*", + "certificateChain": null, + "hostaddress": { + "hostname": "34.70.108.163", + "port": 1789 + }, + "keyFile": null + }, + "maxPeerCount": 100, + "private": false, + "ignoreBootstrapNodes": false, + "maxSessionCount": 8, + "bootstrapReachability": 0.5, + "sessionTimeout": 300, + "peers": [ + { + "address": { + "hostname": "us-e1.chainweb.com", + "port": 443 + }, + "id": null + }, + { + "address": { + "hostname": "us-w1.chainweb.com", + "port": 443 + }, + "id": null + } + ] + }, + "transactionIndex": { + "enabled": true, + "configuration": {} + }, + "gasLimitOfBlock": 150000, + "reorgLimit": 480, + "headerStream": true, + "mempoolP2p": { + "enabled": true, + "configuration": { + "pollInterval": 30, + "maxSessionCount": 6, + "sessionTimeout": 240 + } + }, + "reintroTxs": true, + "cuts": { + "pruneChainDatabase": "none", + "fetchTimeout": 3000000, + "initialCutHeightLimit": null + } + } + } + } + } + } + } + } + }, + "/make-backup": { + "post": { + "summary": "Start a backup job", + "description": "Backup jobs are identified by the Unix timestamp when they're begun.\n\nIf a backup job is already in progress, this endpoint will return its\nidentifier instead of starting a new one.\n\nThe RocksDB portion of the database is always backed up; if backupPact\nis set, the Sqlite (Pact) portion is backed up as well, taking much\nlonger.\n\nThere is no automatic backup retention policy - users need to delete old\nbackups.\n\nThis API is enabled by configuring the node thus:\n```yaml\nbackup:\n api:\n enabled: true\n directory: {some file path to put backups in}\n```\nThe backup directory ideally will be located in the same partition as the\nRocksDB portion of the node database.\n\nRocksDB backups to the same partition as holds the active RocksDB\ndatabase will have almost zero space overhead immediately, but over time\nas the active database diverges from the backup the space overhead will\nincrease. If the backup is to another partition, it will take longer\nand take as much disk space as the active RocksDB database.\n\nPact database backups always require about as much space as the active\nPact database does.\n", + "tags": [ + "misc" + ], + "parameters": [ + { + "$ref": "#/components/parameters/backupPact" + } + ], + "responses": { + "200": { + "description": "A backup job has been created", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/backupId" + } + } + } + } + } + } + }, + "/check-backup/{backupId}": { + "get": { + "summary": "Check the status of a backup job", + "tags": [ + "misc" + ], + "parameters": [ + { + "$ref": "#/components/parameters/backupId" + } + ], + "responses": { + "200": { + "description": "A backup job with that identifier exists, here is its status", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/backupStatus" + } + } + } + }, + "404": { + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "description": "There is no backup job with that identifier" + } + } + } + }, + "/health-check": { + "servers": [ + { + "url": "https://api.chainweb.com", + "description": "Chainweb service API for mainnet" + }, + { + "url": "https://api.testnet.chainweb.com", + "description": "Chainweb service API for testnet" + }, + { + "url": "{schema}://{domain}:{port}", + "description": "Service API endpoint of a chainweb-node. It may serve only a subset of\nthe endpoints.\n", + "variables": { + "schema": { + "default": "http", + "enum": [ + "http", + "https" + ] + }, + "domain": { + "default": "api.chainweb.com" + }, + "port": { + "default": "1848" + } + } + } + ], + "get": { + "tags": [ + "misc" + ], + "summary": "Health Check", + "description": "Checks whether the chainweb-node is up and running and responding to API\nrequests. In order to check the state of consensus the\n[/cut/get](#tag/cut/paths/~1cut/get) endpoint should be used instead.\n", + "responses": { + "200": { + "description": "The node is healthy", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "text/plain": { + "schema": { + "type": "string" + }, + "example": "Health check OK." + } + } + } + } + } + }, + "/info": { + "servers": [ + { + "url": "https://api.chainweb.com", + "description": "Chainweb service API for mainnet" + }, + { + "url": "https://api.testnet.chainweb.com", + "description": "Chainweb service API for testnet" + }, + { + "url": "{schema}://{domain}:{port}", + "description": "Service API endpoint of a chainweb-node. It may serve only a subset of\nthe endpoints.\n", + "variables": { + "schema": { + "default": "http", + "enum": [ + "http", + "https" + ] + }, + "domain": { + "default": "api.chainweb.com" + }, + "port": { + "default": "1848" + } + } + } + ], + "get": { + "tags": [ + "misc" + ], + "summary": "General Node Info", + "description": "Provides general information about the node and the chainweb version", + "responses": { + "200": { + "description": "General information about the node and the chainweb version", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/nodeInfo" + }, + "example": { + "value": { + "nodeNumberOfChains": 20, + "nodeApiVersion": "0.0", + "nodeChains": [ + "12", + "13", + "14", + "15", + "8", + "9", + "10", + "11", + "4", + "5", + "6", + "7", + "0", + "16", + "1", + "17", + "2", + "18", + "3", + "19" + ], + "nodeVersion": "mainnet01", + "nodeGraphHistory": [ + [ + 0, + [ + [ + 0, + [ + 5, + 2, + 3 + ] + ], + [ + 1, + [ + 4, + 6, + 3 + ] + ], + [ + 2, + [ + 4, + 7, + 0 + ] + ], + [ + 3, + [ + 8, + 0, + 1 + ] + ], + [ + 4, + [ + 9, + 1, + 2 + ] + ], + [ + 5, + [ + 9, + 6, + 0 + ] + ], + [ + 6, + [ + 5, + 7, + 1 + ] + ], + [ + 7, + [ + 8, + 6, + 2 + ] + ], + [ + 8, + [ + 9, + 7, + 3 + ] + ], + [ + 9, + [ + 8, + 4, + 5 + ] + ] + ] + ], + [ + 852054, + [ + [ + 0, + [ + 15, + 10, + 5 + ] + ], + [ + 1, + [ + 11, + 6, + 16 + ] + ], + [ + 2, + [ + 12, + 7, + 17 + ] + ], + [ + 3, + [ + 13, + 8, + 18 + ] + ], + [ + 4, + [ + 14, + 9, + 19 + ] + ], + [ + 5, + [ + 8, + 7, + 0 + ] + ], + [ + 6, + [ + 8, + 9, + 1 + ] + ], + [ + 7, + [ + 9, + 5, + 2 + ] + ], + [ + 8, + [ + 5, + 6, + 3 + ] + ], + [ + 9, + [ + 4, + 6, + 7 + ] + ], + [ + 10, + [ + 11, + 0, + 19 + ] + ], + [ + 11, + [ + 12, + 10, + 1 + ] + ], + [ + 12, + [ + 13, + 11, + 2 + ] + ], + [ + 13, + [ + 12, + 14, + 3 + ] + ], + [ + 14, + [ + 13, + 15, + 4 + ] + ], + [ + 15, + [ + 14, + 0, + 16 + ] + ], + [ + 16, + [ + 15, + 1, + 17 + ] + ], + [ + 17, + [ + 16, + 2, + 18 + ] + ], + [ + 18, + [ + 17, + 3, + 19 + ] + ], + [ + 19, + [ + 10, + 4, + 18 + ] + ] + ] + ] + ] + } + } + } + } + } + } + } + }, + "/header/updates": { + "get": { + "tags": [ + "misc" + ], + "summary": "Blocks Event Stream", + "description": "An source of server events that emits a `BlockHeader` event for each new\nblock header that is added to the chain database of the remote node.\n\nThe stream contains blocks that may later become orphaned. It is\ntherefor recommended to buffer events on the client side for the most\nrecent block heights until the desired confirmation depth is reached.\n\nThe server may terminate this stream from time to time and it is up to\nthe client to reinitiate the stream.\n", + "responses": { + "200": { + "description": "A stream of `BlockHeader` events. **This is not a JSON array**.\n\nEvents are separated by empty lines. Each event consists of an\n`event` property and a `data` property which are separated by\nnewlines.\n", + "headers": { + "x-peer-addr": { + "$ref": "#/components/headers/x-peer-addr" + }, + "x-server-timestamp": { + "$ref": "#/components/headers/x-server-timestamp" + }, + "x-chainweb-node-version": { + "$ref": "#/components/headers/x-chainweb-node-version" + } + }, + "content": { + "text/event-stream": { + "schema": { + "description": "A stream of `BlockHeader` events. **This is not an JSON array**.\n\nEvents are separated by empty lines (`\\n\\n`). Each event\nconsists of two newline (`\\n`) separated properties.\n", + "type": "array", + "items": { + "description": "A `BlockHeader` event. **This is not an JSON object**.\n\nEach event consists of an `event` property and a `data`\nproperty which are separated by newlines.\n", + "properties": { + "event": { + "type": "string", + "enum": [ + "BlockHeader" + ] + }, + "data": { + "properties": { + "txCount": { + "type": "integer", + "minimum": 0, + "description": "Number of transactions in the block" + }, + "powHash": { + "type": "string", + "description": "A custom representation of the POW hash for use in the block explorer UI" + }, + "header": { + "$ref": "#/components/schemas/blockHeader" + }, + "target": { + "type": "string", + "description": "A custom representation of the POW target for use in the block explorer UI" + } + } + } + } + } + }, + "example": "event:BlockHeader\ndata:{\"txCount\":0,\"powHash\":\"00000000000006e0b164858ee0fcbfd112f4242d5010ff33d3a43d2cc3c15177\",\"header\":{\"creationTime\":1619037443761924,\"parent\":\"qaUtvtXk75nXsWM9l6vkeGkQilZfE_YgzWkZm-7tLyE\",\"height\":1554652,\"hash\":\"okI4V9Pez5-UPw4nys2Nk9iIPz3-n30HCag5_NQptlo\",\"chainId\":6,\"weight\":\"d8mOCoZeFpajAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\"featureFlags\":0,\"epochStart\":1619035890499046,\"adjacents\":{\"1\":\"OTcNZsNMA-TZ9RTlfWqegFiE0ZkBYcy3JCzh23gmm9Y\",\"8\":\"nznrNdU8RWatTVlS8yTaVaxk8CT1ZjR4ZWta7GAaMDk\",\"9\":\"CanRK_wW8RjyA1X9xSEQCXymsnk3VERAJtAB2abrY_M\"},\"payloadHash\":\"cT86RaKJUyCZXKB3gYqX9A9SNway-lUBrHSvNr7_SaM\",\"chainwebVersion\":\"mainnet01\",\"target\":\"zklwTetkWv91YxYIRmXCt6kUHpEBpiN8gwcAAAAAAAA\",\"nonce\":\"3399765038640884059\"},\"target\":\"00000000000007837c23a601911e14a9b7c2654608166375ff5a64eb4d7049ce\"}\n\nevent:BlockHeader\ndata:{\"txCount\":0,\"powHash\":\"00000000000001c40ddfd6574f9962a443714f3817bbea773a55fec63c7d95c8\",\"header\":{\"creationTime\":1619037446256086,\"parent\":\"usmNftUR_mHpXOm8gCvtbZ50_9VaefaIVvcMdrKwc5A\",\"height\":1554652,\"hash\":\"SOfbK_kI_9BtgLemWmb3FWOgDCTxf1tPulKCq1ndmWA\",\"chainId\":18,\"weight\":\"i7XsQnkhY9yLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\"featureFlags\":0,\"epochStart\":1619035885828397,\"adjacents\":{\"19\":\"fQJ5JKQLdGEwZIoC5HrhJstk3Iibj_a2dfmJl9osG-o\",\"17\":\"L-GeIWZE4fMCICSpPptsfYpsLj3oO5eCiyJimclYJiY\",\"3\":\"V7m9ROQmJs2i1UI05t8J6rjkfg7m795esdsIjhqyqfc\"},\"payloadHash\":\"Ji7WisfH5IulPMcFglexGcVDnA59aS5k1YSE2_6L4t8\",\"chainwebVersion\":\"mainnet01\",\"target\":\"tvH4nBuGx3opw-50T8-i6ECi68IgpFLOjAcAAAAAAAA\",\"nonce\":\"9499180874660840183\"},\"target\":\"000000000000078cce52a420c2eba240e8a2cf4f74eec3297ac7861b9cf8f1b6\"}\n" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/packages/libs/chainweb-node-client/openapi/pact.json b/packages/libs/chainweb-node-client/openapi/pact.json new file mode 100644 index 0000000000..45482f051c --- /dev/null +++ b/packages/libs/chainweb-node-client/openapi/pact.json @@ -0,0 +1,1316 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Pact REST API", + "description": "Transactional API for a runtime offering Pact smart contracts.\n", + "version": "1.3.7", + "x-logo": { + "url": "https://i.imgur.com/bAZFAGF.png", + "alttext": "Kadena Chainweb Logo" + } + }, + "servers": [ + { + "url": "https://api.chainweb.com/chainweb/{apiVersion}/mainnet01/chain/{chainId}/pact/api/v1", + "description": "Pact API for a chain on the Kadena mainnet.", + "variables": { + "apiVersion": { + "default": "0.0" + }, + "chainId": { + "default": "0" + } + } + }, + { + "url": "https://api.testnet.chainweb.com/chainweb/{apiVersion}/testnet04/chain/{chainId}/pact/api/v1", + "description": "Pact API for a chain on the Kadena testnet.", + "variables": { + "apiVersion": { + "default": "0.0" + }, + "chainId": { + "default": "0" + } + } + } + ], + "paths": { + "/local": { + "post": { + "description": "Blocking/sync call to submit a command for non-transactional execution. In a\nblockchain environment this would be a node-local “dirty read”, which can\neither serve as a node-local repl execution, or fully gassed transaction\nsimulation and transaction validation. Any database writes or changes to the\nenvironment are rolled back.\n", + "tags": [ + "endpoint-local" + ], + "summary": "local", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/command" + } + } + } + }, + "parameters": [ + { + "name": "preflight", + "in": "query", + "description": "Trigger fully-gassed mainnet transaction execution simulation and\ntransaction metadata validations.\n", + "required": false, + "schema": { + "type": "bool" + } + }, + { + "name": "signatureValidation", + "in": "query", + "description": "Require user signature validation when validating transaction\nmetadata.\n", + "required": false, + "schema": { + "type": "bool" + } + } + ], + "responses": { + "200": { + "description": "The command's result.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/command-result" + } + } + } + }, + "400": { + "description": "The command was invalid.", + "content": { + "text/plain": { + "type": "string", + "example": "Validation failed: Invalid command: Failed reading: empty", + "schema": { + "$ref": "#/components/schemas/validation-failure" + } + } + } + } + } + } + }, + "/send": { + "post": { + "description": "Asynchronous submission of one or more public (unencrypted) commands\nto the blockchain for execution.\n", + "tags": [ + "endpoint-send" + ], + "summary": "send", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "cmds" + ], + "properties": { + "cmds": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/command" + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "The commands were successfully submitted. The response contains their request keys.", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "requestKeys" + ], + "properties": { + "requestKeys": { + "description": "Request keys for use with `poll` or `listen` to retrieve results.", + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/request-key" + } + } + } + } + } + } + }, + "400": { + "description": "The command failed.", + "content": { + "text/plain": { + "type": "string", + "example": "Validation failed for hash \"j5f3mZaF9pVA7OmV4nTuw5-paG9LzLQJWAMuGGRRLeQ\": Attempt to buy gas failed with: (read coin-table sender): Failure: Tx Failed: read: row not found: 368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca", + "schema": { + "$ref": "#/components/schemas/validation-failure" + } + } + } + } + } + } + }, + "/poll": { + "post": { + "description": "Allows polling for one or more command results by request key.\n", + "summary": "poll", + "tags": [ + "endpoint-poll" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "requestKeys" + ], + "properties": { + "requestKeys": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/request-key" + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "The command results for some of the requested request keys.", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/command-result" + } + } + } + } + } + } + } + }, + "/listen": { + "post": { + "description": "Blocking request for single command result.\n", + "summary": "listen", + "tags": [ + "endpoint-listen" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "listen" + ], + "properties": { + "listen": { + "$ref": "#/components/schemas/request-key" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "The request key was found.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/command-result" + } + } + } + } + } + } + }, + "/private": { + "post": { + "description": "Asynchronous submission of a single addressed command which\nwill be transmitted with end-to-end encryption only between addressed entity nodes.\nPrivate payload metadata required.\n", + "tags": [ + "endpoint-private" + ], + "summary": "private", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/command" + } + } + } + }, + "responses": { + "200": { + "description": "The command was accepted.", + "content": { + "application/json": { + "type": "object", + "schema": { + "properties": { + "requestKeys": { + "description": "Request keys for use with `poll` or `listen` to retrieve results.", + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "$ref": "#/components/schemas/request-key" + } + } + } + } + } + } + } + } + } + }, + "/spv": { + "servers": [ + { + "url": "https://api.chainweb.com/chainweb/{apiVersion}/mainnet01/chain/{chainId}/pact", + "description": "Pact API for a chain on the Kadena mainnet.", + "variables": { + "apiVersion": { + "default": "0.0" + }, + "chainId": { + "default": "0" + } + } + }, + { + "url": "https://api.testnet.chainweb.com/chainweb/{apiVersion}/testnet04/chain/{chainId}/pact", + "description": "Pact API for a chain on the Kadena testnet.", + "variables": { + "apiVersion": { + "default": "0.0" + }, + "chainId": { + "default": "0" + } + } + } + ], + "post": { + "description": "Blocking request to fetch spv proof of a cross chain transaction. Request must be sent to the chain where the transaction is initiated.\n", + "summary": "spv", + "tags": [ + "endpoint-spv" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spv-object" + } + } + } + }, + "responses": { + "200": { + "description": "The requested spv proof.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/spv-proof" + } + } + } + }, + "400": { + "description": "The requested spv proof was not findable.", + "content": { + "text/plain": { + "example": "SPV target not reachable: target chain not reachable. Chainweb instance is too young", + "schema": { + "description": "Error message with the description of failed proof requests.", + "type": "string" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "command": { + "title": "Pact Command", + "tags": [ + "model-command" + ], + "description": "Represents a single blockchain Pact transaction.", + "type": "object", + "required": [ + "cmd", + "hash", + "sigs" + ], + "example": { + "hash": "H6XjdPHzMai2HLa3_yVkXfkFYMgA0bGfsB0kOsHAMuI", + "sigs": [ + { + "sig": "8d452109cc0439234c093b5e204a7428bc0a54f22704402492e027aaa9375a34c910d8a468a12746d0d29e9353f4a3fbebe920d63bcc7963853995db015d060f" + } + ], + "cmd": "{\"payload\":{\"exec\":{\"data\":null,\"code\":\"(+ 1 2)\"}},\"signers\":[{\"pubKey\":\"368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca\"}],\"meta\":{\"gasLimit\":1000,\"chainId\":\"0\",\"gasPrice\":1.0e-2,\"sender\":\"368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca\"},\"nonce\":\"nonce-value\"}" + }, + "properties": { + "cmd": { + "description": "Stringified JSON `payload` object. Canonic non-malleable signed transaction data.\n", + "type": "string" + }, + "hash": { + "description": "Unpadded Base64URL of Blake2s-256 hash of the `cmd` field value. Serves as a command\n`requestKey` since each transaction must be unique.\n", + "type": "string", + "contentEncoding": "base64url", + "example": "H6XjdPHzMai2HLa3_yVkXfkFYMgA0bGfsB0kOsHAMuI" + }, + "sigs": { + "description": "List of signatures corresponding one-to-one with `signers` array in the payload.\n", + "type": "array", + "minItems": 0, + "items": { + "properties": { + "sig": { + "type": "string", + "contentEncoding": "base16", + "description": "Base16-encoded cryptograhic signature of `cmd` field data\nfor corresponding signer in payload.\n", + "example": "8d452109cc0439234c093b5e204a7428bc0a54f22704402492e027aaa9375a34c910d8a468a12746d0d29e9353f4a3fbebe920d63bcc7963853995db015d060f" + } + } + } + } + } + }, + "payload": { + "description": "Pact Command Payloads are encoded as strings in Pact commands, and contain all\nnon-malleable data for a transaction.\n", + "tags": [ + "model-payload" + ], + "type": "object", + "required": [ + "payload", + "meta", + "signers", + "networkId", + "nonce" + ], + "example": { + "payload": { + "exec": { + "data": null, + "code": "(coin.transfer \"Alice\" \"Bob\" 10.0)" + } + }, + "signers": [ + { + "pubKey": "368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca", + "clist": [ + { + "name": "coin.TRANSFER", + "args": [ + "Alice", + "Bob", + 10 + ] + } + ] + } + ], + "meta": { + "gasLimit": 1000, + "chainId": "0", + "gasPrice": 0.01, + "sender": "368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca" + }, + "nonce": "nonce-value" + }, + "properties": { + "payload": { + "oneOf": [ + { + "title": "Exec Message", + "description": "Standard pact execution.", + "properties": { + "code": { + "type": "string", + "description": "Executable pact code." + }, + "data": { + "description": "Arbitrary JSON to be accessed via `read-msg`, `read-integer` et al in Pact code." + } + } + }, + { + "title": "Continuation Message", + "description": "Continuation of a previous transaction defpact.", + "properties": { + "pactId": { + "type": "string", + "description": "ID of pact running previous step." + }, + "step": { + "type": "number", + "description": "Step in defpact to execute." + }, + "rollback": { + "type": "boolean", + "description": "Whether to execute a specified rollback on this step." + }, + "data": { + "description": "Arbitrary JSON to be accessed via `read-msg`, `read-integer` et al in Pact code." + }, + "proof": { + "type": "string", + "contentEncoding": "base64url", + "description": "Backend-specific data for continuing a cross-chain proof." + } + } + } + ] + }, + "meta": { + "oneOf": [ + { + "title": "Public metadata (Chainweb)", + "description": "Chainweb/public command metadata.", + "required": [ + "chainId", + "sender", + "gasLimit", + "gasPrice", + "ttl", + "creationTime" + ], + "properties": { + "chainId": { + "type": "string", + "description": "Platform-specific chain identifier. For chainweb this is the stringified chain number." + }, + "sender": { + "type": "string", + "description": "Indicates gas-paying account." + }, + "gasLimit": { + "type": "number", + "minimum": 1, + "description": "Limits total amount of gas to be consumed." + }, + "gasPrice": { + "type": "number", + "description": "Specifies price per gas unit to be charged." + }, + "ttl": { + "type": "number", + "minimum": 1, + "maximum": 180000, + "description": "Time in seconds after creation time that transaction can be executed." + }, + "creationTime": { + "type": "number", + "description": "POSIX epoch sending time for transaction." + } + } + }, + { + "title": "Private metadata (Kuro)", + "description": "Metadata for Kuro endpoints, including `private`.", + "properties": { + "address": { + "description": "Private message envelope address. Required only for private messages, otherwise null.", + "required": [ + "from", + "to" + ], + "properties": { + "from": { + "type": "string", + "description": "Sender entity name" + }, + "to": { + "description": "Recipient entity names", + "type": "array", + "minItems": 1, + "items": { + "type": "string", + "description": "Recipient entity name" + } + } + } + } + } + } + ] + }, + "signers": { + "description": "List of signers, corresponding with list of signatures in outer command.", + "type": "array", + "items": { + "title": "Signer", + "required": [ + "pubKey" + ], + "properties": { + "pubKey": { + "type": "string", + "description": "Public key image. Pact default is base16 ED25519 encoding." + }, + "address": { + "type": "string", + "description": "Address, if any. Pact default expects this to match pubKey." + }, + "scheme": { + "type": "string", + "description": "Signer scheme. Default is ED25519.", + "enum": [ + "ED25519", + "ETH" + ] + }, + "clist": { + "description": "List of capabilities associated with/installed by this signer.", + "properties": { + "name": { + "type": "string", + "description": "Fully-qualified capability name." + }, + "args": { + "type": "array", + "items": { + "$ref": "#/components/schemas/pact-value" + } + } + } + } + } + } + }, + "networkId": { + "description": "Backend-specific identifier of target network.", + "type": "string", + "enum": [ + "mainnet01", + "testnet04" + ] + }, + "nonce": { + "description": "Arbitrary user-supplied value.", + "type": "string" + } + } + }, + "spv-object": { + "description": "Object consisting of data required to fetch proof of a cross chain transaction\n", + "type": "object", + "required": [ + "requestKey", + "targetChainId" + ], + "properties": { + "requestKey": { + "type": "string", + "description": "Request Key of an initiated cross chain transaction at the source chain.", + "example": "7af34f24d55d2fcf5de6fccfeeb837698ebff4598303237c64348a47806c8646" + }, + "targetChainId": { + "type": "string", + "description": "Target chain id of the cross chain transaction.", + "example": "1" + } + } + }, + "command-result": { + "title": "Command Result", + "tags": [ + "model-command-result" + ], + "example": { + "gas": 123, + "result": { + "status": "success", + "data": 3 + }, + "reqKey": "cQ-guhschk0wTvMBtrqc92M7iYm4S2MYhipQ2vNKxoI", + "logs": "wsATyGqckuIvlm89hhd2j4t6RMkCrcwJe_oeCYr7Th8", + "metaData": null, + "continuation": null, + "txId": "456", + "events": [ + { + "name": "TRANSFER", + "params": [ + "Alice", + "Bob", + 10 + ], + "module": "coin", + "moduleHash": "ut_J_ZNkoyaPUEJhiwVeWnkSQn9JT9sQCWKdjjVVrWo" + } + ] + }, + "description": "The result of attempting to execute a single well-formed Pact command.", + "type": "object", + "required": [ + "reqKey", + "result", + "logs", + "metaData", + "gas" + ], + "properties": { + "reqKey": { + "$ref": "#/components/schemas/request-key" + }, + "result": { + "oneOf": [ + { + "title": "Success", + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "success" + ] + }, + "data": { + "$ref": "#/components/schemas/pact-value" + } + } + }, + { + "title": "Failure", + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "failure" + ] + }, + "error": { + "$ref": "#/components/schemas/pact-error" + } + } + } + ] + }, + "txId": { + "type": "number", + "description": "Database-internal transaction tracking ID." + }, + "logs": { + "type": "string", + "description": "Backend-specific value providing image of database logs." + }, + "metaData": { + "properties": { + "blockTime": { + "type": "number", + "description": "POSIX time of block" + }, + "prevBlockHash": { + "type": "string", + "description": "Parent Block hash of containing block." + }, + "blockHash": { + "type": "string", + "description": "Block hash of containing block." + }, + "blockHeight": { + "type": "number", + "description": "Block height of containing block." + }, + "publicMeta": { + "type": "object", + "description": "Public metadata.", + "properties": { + "creationTime": { + "type": "number", + "description": "POSIX time the command was created" + }, + "ttl": { + "type": "number", + "description": "Transaction time to live" + }, + "gasLimit": { + "type": "number", + "description": "The transaction's gas limit" + }, + "chainId": { + "type": "string", + "description": "Chain identifier" + }, + "gasPrice": { + "type": "number", + "description": "The price of each unit of gas in KDA" + }, + "sender": { + "type": "string" + } + } + } + } + }, + "events": { + "type": "array", + "items": { + "$ref": "#/components/schemas/event" + } + }, + "continuation": { + "description": "Describes result of a defpact execution.", + "properties": { + "pactId": { + "type": "string", + "description": "Identifies this defpact execution. On first step generally matches request key." + }, + "step": { + "type": "number", + "description": "Identifies which step executed in defpact." + }, + "stepCount": { + "type": "number", + "description": "Total number of steps in pact." + }, + "executed": { + "type": "boolean", + "description": "optional value for private pacts, indicates if step was skipped." + }, + "stepHasRollback": { + "type": "boolean", + "description": "indicates if pact step has rollback." + }, + "continuation": { + "description": "Closure describing executed pact.", + "properties": { + "def": { + "type": "string", + "description": "Fully-qualified defpact name." + }, + "args": { + "type": "array", + "items": { + "$ref": "#/components/schemas/pact-value" + } + } + } + }, + "yield": { + "description": "Value yielded during pact step, optionally indicating cross-chain execution.", + "properties": { + "data": { + "type": "object", + "description": "Pact value object containing yielded data.", + "additionalProperties": { + "$ref": "#/components/schemas/pact-value" + } + }, + "source": { + "type": "string", + "description": "Source chain ID." + }, + "provenance": { + "properties": { + "targetChainId": { + "type": "string", + "description": "Chain ID of target chain for next step." + }, + "moduleHash": { + "description": "Hash of module executing defpact.", + "type": "string" + } + } + } + } + } + } + }, + "gas": { + "type": "number" + } + } + }, + "pact-value": { + "description": "Pact value compound type.", + "tags": [ + "model-pact-value" + ], + "anyOf": [ + { + "title": "String", + "description": "Pact strings encode directly to JSON strings.", + "type": "string" + }, + { + "title": "Decimal", + "description": "There are two alternative JSON representations for Decimal.", + "oneOf": [ + { + "title": "Number", + "description": "JSON numbers can be used whenever the precision is adequate\n", + "type": "number" + }, + { + "title": "Object", + "description": "When JSON number precision is not enough, you can use an object with the number's decimal representation as a string\n", + "type": "object", + "required": [ + "decimal" + ], + "properties": { + "decimal": { + "type": "string", + "description": "String representation of number to avoid rounding error", + "example": "1.23498218000001" + } + } + } + ] + }, + { + "title": "Integer", + "description": "There are two alternative JSON representations for Integer.", + "type": "object", + "required": [ + "int" + ], + "properties": { + "int": { + "oneOf": [ + { + "title": "Number", + "description": "JSON numbers are rounded to integer values.\n", + "type": "number", + "example": 12345 + }, + { + "title": "String", + "description": "When JSON number precision is not enough, you can specify the integer as a string\n", + "type": "string", + "example": "123456789" + } + ] + } + } + }, + { + "title": "Boolean", + "description": "JSON booleans encode to Pact booleans.", + "type": "boolean" + }, + { + "title": "Object", + "type": "object", + "description": "JSON objects not matching other Pact Value schemas become Pact objects.", + "additionalProperties": { + "$ref": "#/components/schemas/pact-value" + } + }, + { + "title": "Time", + "type": "object", + "required": [ + "time" + ], + "properties": { + "time": { + "type": "string", + "description": "Literal time value using the UTC time format.", + "example": "1970-01-01T00:00:00Z" + } + } + }, + { + "title": "List", + "description": "JSON lists become Pact lists.", + "type": "array", + "items": { + "$ref": "#/components/schemas/pact-value" + } + }, + { + "title": "Module Reference", + "description": "Special pact value to directly reference a module or interface.", + "type": "object", + "properties": { + "refName": { + "type": "string", + "description": "Fully-qualified module or interface name." + } + } + }, + { + "title": "Guard", + "description": "Special pact value for guard types.", + "type": "object", + "oneOf": [ + { + "title": "Keyset", + "description": "A keyset forms a rule made from a set of key/address values and a predicate function.\nWhen enforced, transaction signer list is evaluated against keyset.\n", + "required": [ + "keys", + "pred" + ], + "properties": { + "keys": { + "type": "array", + "description": "Set of public key/address values. Native pact public keys are ED25519 in base16 encoding.", + "items": { + "type": "string" + } + }, + "pred": { + "type": "string", + "description": "A pact function name. Built-in values are `keys-all` (match all keys in set),\n`keys-any` (match at least one), and `keys-2` (match at least 2).\nCustom functions have a fully-qualified name and\nmust accept two integer arguments `count` (number of keys in set) and `matched`\n(number of set keys found in transaction set).\n" + } + } + }, + { + "title": "Keyset Reference", + "description": "Refers to a keyset in the Pact environment/database installed with `define-keyset`.", + "required": [ + "keysetref" + ], + "properties": { + "keysetref": { + "type": "string", + "description": "Installed keyset name." + } + } + }, + { + "title": "User Guard", + "description": "Closure of call to \"guard function\" which is a boolean user function with arguments.\n", + "required": [ + "fun", + "args" + ], + "properties": { + "fun": { + "description": "Fully-qualified guard function name.", + "type": "string" + }, + "args": { + "description": "Argument values to the guard function.", + "type": "array", + "items": { + "$ref": "#/components/schemas/pact-value" + } + } + } + }, + { + "title": "Module Guard", + "type": "object", + "description": "Autonomous guard that only allows module code access, or requires module admin.\n", + "required": [ + "moduleName", + "name" + ], + "properties": { + "moduleName": { + "required": [ + "name", + "namespace" + ], + "properties": { + "name": { + "type": "string", + "description": "module bare name" + }, + "namespace": { + "type": "string", + "description": "module namespace" + } + } + }, + "name": { + "type": "string", + "description": "Distinguishing/informative name for module guard." + } + } + }, + { + "title": "Pact Guard", + "type": "object", + "description": "Autonomous guard that only allows a particular pact execution, referenced by ID, to pass.\nTwo executions of the same defpact code result in distinct pact IDs. A pact guard\ncreated inside of this execution will only pass when running that particular pact.\n", + "required": [ + "pactId", + "name" + ], + "properties": { + "pactId": { + "description": "Defpact execution ID.", + "type": "string" + }, + "name": { + "type": "string", + "description": "Distinguishing/informative name for pact guard." + } + } + } + ] + } + ] + }, + "event": { + "description": "Pact output event.", + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Event defcap name." + }, + "module": { + "type": "object", + "description": "Qualified module name of event defcap.", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "description": "module bare name" + }, + "namespace": { + "type": "string", + "description": "module namespace" + } + } + }, + "params": { + "type": "array", + "items": { + "$ref": "#/components/schemas/pact-value" + } + }, + "moduleHash": { + "type": "string", + "description": "Hash of emitting module." + } + } + }, + "pact-error": { + "description": "Verbose object describing failed execution.\n", + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string", + "description": "Descriptive error text." + }, + "callStack": { + "type": "array", + "items": { + "type": "string" + } + }, + "info": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "request-key": { + "title": "Request Key", + "type": "string", + "description": "Unique ID of a pact transaction consisting of its hash.", + "pattern": "^[a-zA-Z0-9_-]{43}$", + "contentEncoding": "base64url", + "minLength": 43, + "maxLength": 43, + "example": "y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw" + }, + "validation-failure": { + "title": "Validation Failure", + "type": "string", + "description": "Failure message of unexecuted command due to an invalid gas payer, meta, or other environments." + }, + "spv-proof": { + "title": "SPV Proof", + "type": "string", + "description": "Backend-specific data for continuing a cross-chain proof.", + "example": "\"eyJzdWJqZWN0Ijp7ImlucHV0IjoiQUJSN0ltZGhjeUk2TlRRMExDSnlaWE4xYkhRaU9uc2ljM1JoZEhWeklqb2ljM1ZqWTJWemN5SXNJbVJoZEdFaU9pSlhjbWwwWlNCemRXTmpaV1ZrWldRaWZTd2ljbVZ4UzJWNUlqb2lZa0Y0TjNOd1dqZFdUbUpZWTNocVZFUkNTamt5U21SdlUyVlFjWGx0U25KNWNXOUNhMWcyUkVoYWJ5SXNJbXh2WjNNaU9pSnBRVTF4Y0ZwaVUxSkRaR2hQUzA1YVVYZzFTMHBOTFZOUlNGRlZXRzF4UlZoUlRIRkNUVVpSVFVkSklpd2laWFpsYm5SeklqcGJleUp3WVhKaGJYTWlPbHNpZEdWemRDMXpaVzVrWlhJaUxDSXpaRGxsT1dZeFptSTBZemt6TnpneU5qWmpZV1JrTmpObE4yRTBOMkkzWVRZME5UTmlaVGsyTVdSaU1ETTNNMlkxWXpWbVlUUXdZV05sWlRaaVpHVm1JaXd4WFN3aWJtRnRaU0k2SWxSU1FVNVRSa1ZTSWl3aWJXOWtkV3hsSWpwN0ltNWhiV1Z6Y0dGalpTSTZiblZzYkN3aWJtRnRaU0k2SW1OdmFXNGlmU3dpYlc5a2RXeGxTR0Z6YUNJNkluVjBYMHBmV2s1cmIzbGhVRlZGU21ocGQxWmxWMjVyVTFGdU9VcFVPWE5SUTFkTFpHcHFWbFp5VjI4aWZWMHNJbTFsZEdGRVlYUmhJanB1ZFd4c0xDSmpiMjUwYVc1MVlYUnBiMjRpT201MWJHd3NJblI0U1dRaU9qRXhOams1TkRaOSJ9LCJhbGdvcml0aG0iOiJTSEE1MTJ0XzI1NiIsIm9iamVjdCI6IkFBQUFFQUFBQUFBQUFBQUJBUGhpTkRUdEFHT0l4dWE4OTFYUGU0NVFRS2QtTFdOekNpc0JDeHlmeDliQ0FPUkRnUUR2RFRrWmdOTzZ2M1ZpbU1wZ2ZGd2kyQm1mZ29jRVdwVmxRRW9EQWVoT1JPeFdBckJidXpldnZLTUdQZTB1RlVfUE8yejM3VC0tY0thdDZ1d3pBVm9DbFVrU1lXaXRDODF0TERVd2JYYVFWRTdnZFp1ckN6d0RiZUlBdlpBcUFKVThWZHZkMS1nYmo2UEtIVXdWQm00UWRvNl9YUkpYdHdKTGE4a0N3OWJhQWQtbXRubnlsUkczOC1WcTZzZmlZWm0xd2tKejhZcU5ZT2gwbVZCTktFR1VBTkdQWlB4NGFhMWFDdTJ1Ty1VRkJXLWxLbFdFeFU0a2JjMkszOFZCT21ZeEFDakxpdjMwazdBaGdwVXBCWUIxcEYwWFRqTmU4d3k4aHQta2FveFFKbTZpQVlXSkFYZlpXZERNdkQ3Z1UydUItWFdTVUh3bVpvM3NzV0stRzh1OTIxempBTzllbVBkOFJRVk5jOWZWZWJHN0lMb2lqVDlYMm9Db1p2Q00xQ29yR3laUUFTLVVZd3c4dkJ1bEVVYXlxaHZEQUFreUthbHk1TXk1bzJYVXZpZlZsNkg5QUM5ZXZsczVxMXh2bGhQbE9UWnJZNVB2SDNFbDd3dTBZTTJQYmZzaE1lUGFBUFpZRFJoWncyXzBVM1hIZllQbmJ6QlQ4bkc3a2gtR09kRTBTcFFCNEVOQ0FVWGEzcGVoMnhVd2dCVHd5WFVvc3RDRjNqQ21Scm9ZRGlEUTVGTGhYNkVQQUdlMUF2cFhJazZFM2tpdnUxY1N4aVFYV0hUcW1pdEUwLTVYaVpjNU4zQ3ZBS1dMNmM1RDdQSV84aW0zbG04cWhtZl84UXp3d2ZFcVpXQXZoQ0dWc1VVdCIsImNoYWluIjoxfQ\"\n" + } + }, + "examples": { + "command": { + "hash": "H6XjdPHzMai2HLa3_yVkXfkFYMgA0bGfsB0kOsHAMuI", + "sigs": [ + { + "sig": "8d452109cc0439234c093b5e204a7428bc0a54f22704402492e027aaa9375a34c910d8a468a12746d0d29e9353f4a3fbebe920d63bcc7963853995db015d060f" + } + ], + "cmd": "{\"payload\":{\"exec\":{\"data\":null,\"code\":\"(+ 1 2)\"}},\"signers\":[{\"pubKey\":\"368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca\"}],\"meta\":{\"gasLimit\":1000,\"chainId\":\"0\",\"gasPrice\":1.0e-2,\"sender\":\"368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca\"},\"nonce\":\"nonce-value\"}" + }, + "command-result": { + "gas": 123, + "result": { + "status": "success", + "data": 3 + }, + "reqKey": "cQ-guhschk0wTvMBtrqc92M7iYm4S2MYhipQ2vNKxoI", + "logs": "wsATyGqckuIvlm89hhd2j4t6RMkCrcwJe_oeCYr7Th8", + "metaData": null, + "continuation": null, + "txId": "456", + "events": [ + { + "name": "TRANSFER", + "params": [ + "Alice", + "Bob", + 10 + ], + "module": "coin", + "moduleHash": "ut_J_ZNkoyaPUEJhiwVeWnkSQn9JT9sQCWKdjjVVrWo" + } + ] + }, + "payload": { + "payload": { + "exec": { + "data": null, + "code": "(coin.transfer \"Alice\" \"Bob\" 10.0)" + } + }, + "signers": [ + { + "pubKey": "368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca", + "clist": [ + { + "name": "coin.TRANSFER", + "args": [ + "Alice", + "Bob", + 10 + ] + } + ] + } + ], + "meta": { + "gasLimit": 1000, + "chainId": "0", + "gasPrice": 0.01, + "sender": "368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca" + }, + "nonce": "nonce-value" + } + } + }, + "x-tagGroups": [ + { + "name": "std-pact-api", + "x-displayName": "Standard Pact API", + "tags": [ + "endpoint-local", + "endpoint-send", + "endpoint-poll", + "endpoint-listen" + ] + }, + { + "name": "private-api", + "x-displayName": "Private Pact API", + "tags": [ + "endpoint-private" + ] + }, + { + "name": "spv-api", + "x-displayName": "SPV API", + "tags": [ + "endpoint-spv" + ] + }, + { + "name": "models", + "x-displayName": "Pact API models", + "tags": [ + "model-command", + "model-command-result", + "model-payload", + "model-pact-value" + ] + } + ], + "tags": [ + { + "name": "endpoint-local", + "x-displayName": "Non-transactional execution" + }, + { + "name": "endpoint-send", + "x-displayName": "Transactional batch execution" + }, + { + "name": "endpoint-poll", + "x-displayName": "Batch polling for results" + }, + { + "name": "endpoint-listen", + "x-displayName": "Blocking listen for single transaction result" + }, + { + "name": "endpoint-private", + "x-displayName": "Private transaction execution" + }, + { + "name": "endpoint-spv", + "x-displayName": "SPV proof creation for cross chain transaction" + }, + { + "name": "model-command", + "x-displayName": "Pact Commands", + "description": "\n" + }, + { + "name": "model-command-result", + "x-displayName": "Pact Command Results", + "description": "\n" + }, + { + "name": "model-payload", + "x-displayName": "Pact Command Payloads", + "description": "\n" + }, + { + "name": "model-pact-value", + "x-displayName": "Pact Values", + "description": "\n" + } + ] +} \ No newline at end of file diff --git a/packages/libs/chainweb-node-client/package.json b/packages/libs/chainweb-node-client/package.json index 4abd0cc097..b9e710477c 100644 --- a/packages/libs/chainweb-node-client/package.json +++ b/packages/libs/chainweb-node-client/package.json @@ -28,6 +28,9 @@ "_phase:build": "heft build --clean", "_phase:test": "heft test --no-build", "build": "heft build --clean", + "generate:chainweb:client": "openapi-typescript ./openapi/chainweb.json --output ./src/openapi/chainweb.ts", + "generate:pact:client": "openapi-typescript ./openapi/pact.json --output ./src/openapi/pact.ts", + "postinstall": "npm run generate:pact:client && npm run generate:chainweb:client", "lint": "npx eslint ./src --ext .js,.ts --fix", "test": "rushx build && heft test --no-build" }, @@ -55,6 +58,8 @@ "@rushstack/heft": "~0.46.1", "@types/heft-jest": "~1.0.3", "@types/node": "^16.0.0", - "eslint": "^8.15.0" + "eslint": "^8.15.0", + "openapi-typescript": "~6.1.0", + "openapi-typescript-fetch": "~1.1.3" } } diff --git a/packages/libs/chainweb-node-client/src/openapi/pact.ts b/packages/libs/chainweb-node-client/src/openapi/pact.ts new file mode 100644 index 0000000000..0a5f0c90a4 --- /dev/null +++ b/packages/libs/chainweb-node-client/src/openapi/pact.ts @@ -0,0 +1,629 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +/** Type helpers */ +type Without = { [P in Exclude]?: never }; +type XOR = T | U extends object + ? (Without & U) | (Without & T) + : T | U; +type OneOf = T extends [infer Only] + ? Only + : T extends [infer A, infer B, ...infer Rest] + ? OneOf<[XOR, ...Rest]> + : never; + +export interface paths { + '/local': { + /** + * local + * @description Blocking/sync call to submit a command for non-transactional execution. In a + * blockchain environment this would be a node-local “dirty read”, which can + * either serve as a node-local repl execution, or fully gassed transaction + * simulation and transaction validation. Any database writes or changes to the + * environment are rolled back. + */ + post: { + /** + * local + * @description Blocking/sync call to submit a command for non-transactional execution. In a + * blockchain environment this would be a node-local “dirty read”, which can + * either serve as a node-local repl execution, or fully gassed transaction + * simulation and transaction validation. Any database writes or changes to the + * environment are rolled back. + */ + parameters?: { + /** + * @description Trigger fully-gassed mainnet transaction execution simulation and + * transaction metadata validations. + */ + /** + * @description Require user signature validation when validating transaction + * metadata. + */ + query?: { + preflight?: Record; + signatureValidation?: Record; + }; + }; + requestBody?: { + content: { + 'application/json': components['schemas']['command']; + }; + }; + responses: { + /** @description The command's result. */ + 200: { + content: { + 'application/json': components['schemas']['command-result']; + }; + }; + /** @description The command was invalid. */ + 400: { + content: { + 'text/plain': components['schemas']['validation-failure']; + }; + }; + }; + }; + }; + '/send': { + /** + * send + * @description Asynchronous submission of one or more public (unencrypted) commands + * to the blockchain for execution. + */ + post: { + /** + * send + * @description Asynchronous submission of one or more public (unencrypted) commands + * to the blockchain for execution. + */ + requestBody?: { + content: { + 'application/json': { + cmds: components['schemas']['command'][]; + }; + }; + }; + responses: { + /** @description The commands were successfully submitted. The response contains their request keys. */ + 200: { + content: { + 'application/json': { + /** @description Request keys for use with `poll` or `listen` to retrieve results. */ + requestKeys: components['schemas']['request-key'][]; + }; + }; + }; + /** @description The command failed. */ + 400: { + content: { + 'text/plain': components['schemas']['validation-failure']; + }; + }; + }; + }; + }; + '/poll': { + /** + * poll + * @description Allows polling for one or more command results by request key. + */ + post: { + /** + * poll + * @description Allows polling for one or more command results by request key. + */ + requestBody?: { + content: { + 'application/json': { + requestKeys: components['schemas']['request-key'][]; + }; + }; + }; + responses: { + /** @description The command results for some of the requested request keys. */ + 200: { + content: { + 'application/json': { + [key: string]: + | components['schemas']['command-result'] + | undefined; + }; + }; + }; + }; + }; + }; + '/listen': { + /** + * listen + * @description Blocking request for single command result. + */ + post: { + /** + * listen + * @description Blocking request for single command result. + */ + requestBody?: { + content: { + 'application/json': { + listen: components['schemas']['request-key']; + }; + }; + }; + responses: { + /** @description The request key was found. */ + 200: { + content: { + 'application/json': components['schemas']['command-result']; + }; + }; + }; + }; + }; + '/private': { + /** + * private + * @description Asynchronous submission of a single addressed command which + * will be transmitted with end-to-end encryption only between addressed entity nodes. + * Private payload metadata required. + */ + post: { + /** + * private + * @description Asynchronous submission of a single addressed command which + * will be transmitted with end-to-end encryption only between addressed entity nodes. + * Private payload metadata required. + */ + requestBody?: { + content: { + 'application/json': components['schemas']['command']; + }; + }; + responses: { + /** @description The command was accepted. */ + 200: { + content: { + 'application/json': { + /** @description Request keys for use with `poll` or `listen` to retrieve results. */ + requestKeys?: components['schemas']['request-key'][]; + }; + }; + }; + }; + }; + }; + '/spv': { + /** + * spv + * @description Blocking request to fetch spv proof of a cross chain transaction. Request must be sent to the chain where the transaction is initiated. + */ + post: { + /** + * spv + * @description Blocking request to fetch spv proof of a cross chain transaction. Request must be sent to the chain where the transaction is initiated. + */ + requestBody?: { + content: { + 'application/json': components['schemas']['spv-object']; + }; + }; + responses: { + /** @description The requested spv proof. */ + 200: { + content: { + 'application/json': components['schemas']['spv-proof']; + }; + }; + /** @description The requested spv proof was not findable. */ + 400: { + content: { + 'text/plain': string; + }; + }; + }; + }; + }; +} + +export type webhooks = Record; + +export interface components { + schemas: { + /** + * Pact Command + * @description Represents a single blockchain Pact transaction. + * @example { + * "hash": "H6XjdPHzMai2HLa3_yVkXfkFYMgA0bGfsB0kOsHAMuI", + * "sigs": [ + * { + * "sig": "8d452109cc0439234c093b5e204a7428bc0a54f22704402492e027aaa9375a34c910d8a468a12746d0d29e9353f4a3fbebe920d63bcc7963853995db015d060f" + * } + * ], + * "cmd": "{\"payload\":{\"exec\":{\"data\":null,\"code\":\"(+ 1 2)\"}},\"signers\":[{\"pubKey\":\"368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca\"}],\"meta\":{\"gasLimit\":1000,\"chainId\":\"0\",\"gasPrice\":1.0e-2,\"sender\":\"368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca\"},\"nonce\":\"nonce-value\"}" + * } + */ + command: { + /** @description Stringified JSON `payload` object. Canonic non-malleable signed transaction data. */ + cmd: string; + /** + * @description Unpadded Base64URL of Blake2s-256 hash of the `cmd` field value. Serves as a command + * `requestKey` since each transaction must be unique. + * + * @example H6XjdPHzMai2HLa3_yVkXfkFYMgA0bGfsB0kOsHAMuI + */ + hash: string; + /** @description List of signatures corresponding one-to-one with `signers` array in the payload. */ + sigs: { + /** + * @description Base16-encoded cryptograhic signature of `cmd` field data + * for corresponding signer in payload. + * + * @example 8d452109cc0439234c093b5e204a7428bc0a54f22704402492e027aaa9375a34c910d8a468a12746d0d29e9353f4a3fbebe920d63bcc7963853995db015d060f + */ + sig?: string; + }[]; + }; + /** + * @description Pact Command Payloads are encoded as strings in Pact commands, and contain all + * non-malleable data for a transaction. + * + * @example { + * "payload": { + * "exec": { + * "data": null, + * "code": "(coin.transfer \"Alice\" \"Bob\" 10.0)" + * } + * }, + * "signers": [ + * { + * "pubKey": "368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca", + * "clist": [ + * { + * "name": "coin.TRANSFER", + * "args": [ + * "Alice", + * "Bob", + * 10 + * ] + * } + * ] + * } + * ], + * "meta": { + * "gasLimit": 1000, + * "chainId": "0", + * "gasPrice": 0.01, + * "sender": "368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca" + * }, + * "nonce": "nonce-value" + * } + */ + payload: { + payload: OneOf< + [ + { + /** @description Executable pact code. */ + code?: string; + /** @description Arbitrary JSON to be accessed via `read-msg`, `read-integer` et al in Pact code. */ + data?: Record; + }, + { + /** @description ID of pact running previous step. */ + pactId?: string; + /** @description Step in defpact to execute. */ + step?: number; + /** @description Whether to execute a specified rollback on this step. */ + rollback?: boolean; + /** @description Arbitrary JSON to be accessed via `read-msg`, `read-integer` et al in Pact code. */ + data?: Record; + /** @description Backend-specific data for continuing a cross-chain proof. */ + proof?: string; + }, + ] + >; + meta: OneOf< + [ + { + /** @description Platform-specific chain identifier. For chainweb this is the stringified chain number. */ + chainId: string; + /** @description Indicates gas-paying account. */ + sender: string; + /** @description Limits total amount of gas to be consumed. */ + gasLimit: number; + /** @description Specifies price per gas unit to be charged. */ + gasPrice: number; + /** @description Time in seconds after creation time that transaction can be executed. */ + ttl: number; + /** @description POSIX epoch sending time for transaction. */ + creationTime: number; + }, + { + /** @description Private message envelope address. Required only for private messages, otherwise null. */ + address?: { + /** @description Sender entity name */ + from: string; + /** @description Recipient entity names */ + to: string[]; + }; + }, + ] + >; + /** @description List of signers, corresponding with list of signatures in outer command. */ + signers: { + /** @description Public key image. Pact default is base16 ED25519 encoding. */ + pubKey: string; + /** @description Address, if any. Pact default expects this to match pubKey. */ + address?: string; + /** + * @description Signer scheme. Default is ED25519. + * @enum {string} + */ + scheme?: 'ED25519' | 'ETH'; + /** @description List of capabilities associated with/installed by this signer. */ + clist?: { + /** @description Fully-qualified capability name. */ + name?: string; + args?: components['schemas']['pact-value'][]; + }; + }[]; + /** + * @description Backend-specific identifier of target network. + * @enum {string} + */ + networkId: 'mainnet01' | 'testnet04'; + /** @description Arbitrary user-supplied value. */ + nonce: string; + }; + /** @description Object consisting of data required to fetch proof of a cross chain transaction */ + 'spv-object': { + /** + * @description Request Key of an initiated cross chain transaction at the source chain. + * @example 7af34f24d55d2fcf5de6fccfeeb837698ebff4598303237c64348a47806c8646 + */ + requestKey: string; + /** + * @description Target chain id of the cross chain transaction. + * @example 1 + */ + targetChainId: string; + }; + /** + * Command Result + * @description The result of attempting to execute a single well-formed Pact command. + * @example { + * "gas": 123, + * "result": { + * "status": "success", + * "data": 3 + * }, + * "reqKey": "cQ-guhschk0wTvMBtrqc92M7iYm4S2MYhipQ2vNKxoI", + * "logs": "wsATyGqckuIvlm89hhd2j4t6RMkCrcwJe_oeCYr7Th8", + * "metaData": null, + * "continuation": null, + * "txId": "456", + * "events": [ + * { + * "name": "TRANSFER", + * "params": [ + * "Alice", + * "Bob", + * 10 + * ], + * "module": "coin", + * "moduleHash": "ut_J_ZNkoyaPUEJhiwVeWnkSQn9JT9sQCWKdjjVVrWo" + * } + * ] + * } + */ + 'command-result': { + reqKey: components['schemas']['request-key']; + result: OneOf< + [ + { + /** @enum {string} */ + status?: 'success'; + data?: components['schemas']['pact-value']; + }, + { + /** @enum {string} */ + status?: 'failure'; + error?: components['schemas']['pact-error']; + }, + ] + >; + /** @description Database-internal transaction tracking ID. */ + txId?: number; + /** @description Backend-specific value providing image of database logs. */ + logs: string; + metaData: { + /** @description POSIX time of block */ + blockTime?: number; + /** @description Parent Block hash of containing block. */ + prevBlockHash?: string; + /** @description Block hash of containing block. */ + blockHash?: string; + /** @description Block height of containing block. */ + blockHeight?: number; + /** @description Public metadata. */ + publicMeta?: { + /** @description POSIX time the command was created */ + creationTime?: number; + /** @description Transaction time to live */ + ttl?: number; + /** @description The transaction's gas limit */ + gasLimit?: number; + /** @description Chain identifier */ + chainId?: string; + /** @description The price of each unit of gas in KDA */ + gasPrice?: number; + sender?: string; + }; + }; + events?: components['schemas']['event'][]; + /** @description Describes result of a defpact execution. */ + continuation?: { + /** @description Identifies this defpact execution. On first step generally matches request key. */ + pactId?: string; + /** @description Identifies which step executed in defpact. */ + step?: number; + /** @description Total number of steps in pact. */ + stepCount?: number; + /** @description optional value for private pacts, indicates if step was skipped. */ + executed?: boolean; + /** @description indicates if pact step has rollback. */ + stepHasRollback?: boolean; + /** @description Closure describing executed pact. */ + continuation?: { + /** @description Fully-qualified defpact name. */ + def?: string; + args?: components['schemas']['pact-value'][]; + }; + /** @description Value yielded during pact step, optionally indicating cross-chain execution. */ + yield?: { + /** @description Pact value object containing yielded data. */ + data?: { + [key: string]: components['schemas']['pact-value'] | undefined; + }; + /** @description Source chain ID. */ + source?: string; + provenance?: { + /** @description Chain ID of target chain for next step. */ + targetChainId?: string; + /** @description Hash of module executing defpact. */ + moduleHash?: string; + }; + }; + }; + gas: number; + }; + /** @description Pact value compound type. */ + 'pact-value': + | string + | OneOf< + [ + number, + { + /** + * @description String representation of number to avoid rounding error + * @example 1.23498218000001 + */ + decimal: string; + }, + ] + > + | { + int: number | string; + } + | boolean + | { + [key: string]: components['schemas']['pact-value'] | undefined; + } + | { + /** + * @description Literal time value using the UTC time format. + * @example 1970-01-01T00:00:00Z + */ + time: string; + } + | components['schemas']['pact-value'][] + | { + /** @description Fully-qualified module or interface name. */ + refName?: string; + } + | OneOf< + [ + { + /** @description Set of public key/address values. Native pact public keys are ED25519 in base16 encoding. */ + keys: string[]; + /** + * @description A pact function name. Built-in values are `keys-all` (match all keys in set), + * `keys-any` (match at least one), and `keys-2` (match at least 2). + * Custom functions have a fully-qualified name and + * must accept two integer arguments `count` (number of keys in set) and `matched` + * (number of set keys found in transaction set). + */ + pred: string; + }, + { + /** @description Installed keyset name. */ + keysetref: string; + }, + { + /** @description Fully-qualified guard function name. */ + fun: string; + /** @description Argument values to the guard function. */ + args: components['schemas']['pact-value'][]; + }, + { + moduleName: { + /** @description module bare name */ + name: string; + /** @description module namespace */ + namespace: string; + }; + /** @description Distinguishing/informative name for module guard. */ + name: string; + }, + { + /** @description Defpact execution ID. */ + pactId: string; + /** @description Distinguishing/informative name for pact guard. */ + name: string; + }, + ] + >; + /** @description Pact output event. */ + event: { + /** @description Event defcap name. */ + name?: string; + /** @description Qualified module name of event defcap. */ + module?: { + /** @description module bare name */ + name: string; + /** @description module namespace */ + namespace?: string; + }; + params?: components['schemas']['pact-value'][]; + /** @description Hash of emitting module. */ + moduleHash?: string; + }; + /** @description Verbose object describing failed execution. */ + 'pact-error': { + /** @description Descriptive error text. */ + message: string; + callStack?: string[]; + info?: string; + type?: string; + }; + /** + * Request Key + * @description Unique ID of a pact transaction consisting of its hash. + * @example y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw + */ + 'request-key': string; + /** + * Validation Failure + * @description Failure message of unexecuted command due to an invalid gas payer, meta, or other environments. + */ + 'validation-failure': string; + /** + * SPV Proof + * @description Backend-specific data for continuing a cross-chain proof. + * @example "eyJzdWJqZWN0Ijp7ImlucHV0IjoiQUJSN0ltZGhjeUk2TlRRMExDSnlaWE4xYkhRaU9uc2ljM1JoZEhWeklqb2ljM1ZqWTJWemN5SXNJbVJoZEdFaU9pSlhjbWwwWlNCemRXTmpaV1ZrWldRaWZTd2ljbVZ4UzJWNUlqb2lZa0Y0TjNOd1dqZFdUbUpZWTNocVZFUkNTamt5U21SdlUyVlFjWGx0U25KNWNXOUNhMWcyUkVoYWJ5SXNJbXh2WjNNaU9pSnBRVTF4Y0ZwaVUxSkRaR2hQUzA1YVVYZzFTMHBOTFZOUlNGRlZXRzF4UlZoUlRIRkNUVVpSVFVkSklpd2laWFpsYm5SeklqcGJleUp3WVhKaGJYTWlPbHNpZEdWemRDMXpaVzVrWlhJaUxDSXpaRGxsT1dZeFptSTBZemt6TnpneU5qWmpZV1JrTmpObE4yRTBOMkkzWVRZME5UTmlaVGsyTVdSaU1ETTNNMlkxWXpWbVlUUXdZV05sWlRaaVpHVm1JaXd4WFN3aWJtRnRaU0k2SWxSU1FVNVRSa1ZTSWl3aWJXOWtkV3hsSWpwN0ltNWhiV1Z6Y0dGalpTSTZiblZzYkN3aWJtRnRaU0k2SW1OdmFXNGlmU3dpYlc5a2RXeGxTR0Z6YUNJNkluVjBYMHBmV2s1cmIzbGhVRlZGU21ocGQxWmxWMjVyVTFGdU9VcFVPWE5SUTFkTFpHcHFWbFp5VjI4aWZWMHNJbTFsZEdGRVlYUmhJanB1ZFd4c0xDSmpiMjUwYVc1MVlYUnBiMjRpT201MWJHd3NJblI0U1dRaU9qRXhOams1TkRaOSJ9LCJhbGdvcml0aG0iOiJTSEE1MTJ0XzI1NiIsIm9iamVjdCI6IkFBQUFFQUFBQUFBQUFBQUJBUGhpTkRUdEFHT0l4dWE4OTFYUGU0NVFRS2QtTFdOekNpc0JDeHlmeDliQ0FPUkRnUUR2RFRrWmdOTzZ2M1ZpbU1wZ2ZGd2kyQm1mZ29jRVdwVmxRRW9EQWVoT1JPeFdBckJidXpldnZLTUdQZTB1RlVfUE8yejM3VC0tY0thdDZ1d3pBVm9DbFVrU1lXaXRDODF0TERVd2JYYVFWRTdnZFp1ckN6d0RiZUlBdlpBcUFKVThWZHZkMS1nYmo2UEtIVXdWQm00UWRvNl9YUkpYdHdKTGE4a0N3OWJhQWQtbXRubnlsUkczOC1WcTZzZmlZWm0xd2tKejhZcU5ZT2gwbVZCTktFR1VBTkdQWlB4NGFhMWFDdTJ1Ty1VRkJXLWxLbFdFeFU0a2JjMkszOFZCT21ZeEFDakxpdjMwazdBaGdwVXBCWUIxcEYwWFRqTmU4d3k4aHQta2FveFFKbTZpQVlXSkFYZlpXZERNdkQ3Z1UydUItWFdTVUh3bVpvM3NzV0stRzh1OTIxempBTzllbVBkOFJRVk5jOWZWZWJHN0lMb2lqVDlYMm9Db1p2Q00xQ29yR3laUUFTLVVZd3c4dkJ1bEVVYXlxaHZEQUFreUthbHk1TXk1bzJYVXZpZlZsNkg5QUM5ZXZsczVxMXh2bGhQbE9UWnJZNVB2SDNFbDd3dTBZTTJQYmZzaE1lUGFBUFpZRFJoWncyXzBVM1hIZllQbmJ6QlQ4bkc3a2gtR09kRTBTcFFCNEVOQ0FVWGEzcGVoMnhVd2dCVHd5WFVvc3RDRjNqQ21Scm9ZRGlEUTVGTGhYNkVQQUdlMUF2cFhJazZFM2tpdnUxY1N4aVFYV0hUcW1pdEUwLTVYaVpjNU4zQ3ZBS1dMNmM1RDdQSV84aW0zbG04cWhtZl84UXp3d2ZFcVpXQXZoQ0dWc1VVdCIsImNoYWluIjoxfQ" + */ + 'spv-proof': string; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} + +export type external = Record; + +export type operations = Record; diff --git a/packages/libs/client/etc/client.api.md b/packages/libs/client/etc/client.api.md index e6b3f950c0..8514d98ce7 100644 --- a/packages/libs/client/etc/client.api.md +++ b/packages/libs/client/etc/client.api.md @@ -25,14 +25,47 @@ export function buildUnsignedTransaction(parts: string[], holes: string[], args: // @alpha (undocumented) export function createPactCommandFromTemplate(tpl: IPactCommand): PactCommand; -// @alpha (undocumented) -export interface IChainweaverQuickSignRequestBody { +// @public (undocumented) +export interface IChainweaverCap { + // (undocumented) + args: Array>; // (undocumented) - cmdSigDatas: IUnsignedChainweaverTransaction[]; + name: string; } -// @alpha (undocumented) -export type IChainweaverSig = string; +// @public (undocumented) +export interface IChainweaverCapElement { + // (undocumented) + cap: IChainweaverCap; + // (undocumented) + description: string; + // (undocumented) + role: string; +} + +// @public (undocumented) +export interface IChainweaverSignBody { + // (undocumented) + caps: IChainweaverCapElement[]; + // (undocumented) + chainId: string; + // (undocumented) + code: string; + // (undocumented) + data: Record; + // (undocumented) + gasLimit: number; + // (undocumented) + gasPrice: number; + // (undocumented) + networkId: string; + // (undocumented) + sender: string; + // (undocumented) + signingPubKey: string; + // (undocumented) + ttl: number; +} // @alpha (undocumented) export interface ICommandBuilder, TArgs extends Array = TCaps[keyof TCaps]> { @@ -43,7 +76,7 @@ export interface ICommandBuilder, TArgs exte // (undocumented) addSignatures(...sig: { pubKey: string; - sig: string | null; + sig: string; }[]): ICommandBuilder & IPactCommand; // (undocumented) createCommand(): ICommand; @@ -92,7 +125,7 @@ export interface IPactCommand { }[]; }[]; // (undocumented) - sigs: (ISignature | undefined | null)[]; + sigs: (ISignature | undefined)[]; // (undocumented) type: string; } @@ -116,11 +149,57 @@ export interface IPublicMeta { } // @alpha (undocumented) -export interface ISigner { +export interface IQuicksignError { + // (undocumented) + error: { + type: 'reject'; + } | { + type: 'emptyList'; + } | { + type: 'other'; + msg: string; + }; +} + +// @alpha (undocumented) +export interface IQuickSignRequestBody { + // (undocumented) + cmdSigDatas: IUnsignedQuicksignTransaction[]; +} + +// @alpha (undocumented) +export interface IQuicksignResponse { + // (undocumented) + commandSigData: IQuicksignResponseCommand; + // (undocumented) + outcome: { + hash: string; + result: 'success'; + } | { + msg: string; + result: 'failure'; + } | { + result: 'noSig'; + }; +} + +// @alpha (undocumented) +export interface IQuicksignResponseCommand { + // (undocumented) + cmd: string; + // (undocumented) + sigs: IQuicksignSigner[]; +} + +// @alpha (undocumented) +export type IQuicksignSig = string | null; + +// @alpha (undocumented) +export interface IQuicksignSigner { // (undocumented) pubKey: string; // (undocumented) - sig: string | null; + sig: IQuicksignSig; } // @alpha (undocumented) @@ -132,11 +211,11 @@ export interface ITemplate { } // @alpha (undocumented) -export interface IUnsignedChainweaverTransaction { +export interface IUnsignedQuicksignTransaction { // (undocumented) cmd: string; // (undocumented) - sigs: ISigner[]; + sigs: IQuicksignSigner[]; } // @alpha (undocumented) @@ -147,7 +226,7 @@ export interface IUnsignedTransaction { hash: string; // (undocumented) sigs: { - [pubkey: string]: string | null; + [pubkey: string]: string | undefined; }; } @@ -170,7 +249,7 @@ export class PactCommand implements IPactCommand, ICommandBuilder & IPactCommand; status: string; @@ -215,7 +214,7 @@ export class PactCommand // convert to IUnsignedTransaction const command: ICommand = { hash, - sigs: this.sigs.map((s) => (!s ? { sig: null } : s)), + sigs: this.sigs.map((s) => (!s ? { sig: undefined } : s)), cmd, }; @@ -380,10 +379,7 @@ export class PactCommand return poll({ requestKeys: [this.requestKey] }, apiHost); } - public addSignatures( - // eslint-disable-next-line @rushstack/no-new-null - ...sigs: { pubKey: string; sig: string | null }[] - ): this { + public addSignatures(...sigs: { pubKey: string; sig: string }[]): this { sigs.forEach(({ pubKey, sig }) => { const foundSignerIndex = this.signers.findIndex( (signer) => signer.pubKey === pubKey, diff --git a/packages/libs/client/src/signing-api/README.md b/packages/libs/client/src/signing-api/README.md new file mode 100644 index 0000000000..0dbc8f88e6 --- /dev/null +++ b/packages/libs/client/src/signing-api/README.md @@ -0,0 +1,4 @@ +# Signing Api + +- Documentation: https://kadena-io.github.io/signing-api/ +- Source: https://github.com/kadena-io/signing-api diff --git a/packages/libs/client/src/signing-api/v1/quicksign.ts b/packages/libs/client/src/signing-api/v1/quicksign.ts new file mode 100644 index 0000000000..e0752b628a --- /dev/null +++ b/packages/libs/client/src/signing-api/v1/quicksign.ts @@ -0,0 +1,72 @@ +/** + * @alpha + */ +export interface IQuickSignRequestBody { + cmdSigDatas: IUnsignedQuicksignTransaction[]; +} + +/** + * @alpha + */ +export interface IQuicksignSigner { + pubKey: string; + sig: IQuicksignSig; +} + +/** + * @alpha + */ +export interface IUnsignedQuicksignTransaction { + sigs: IQuicksignSigner[]; + cmd: string; +} + +/** + * @alpha + */ +// eslint-disable-next-line @rushstack/no-new-null +export type IQuicksignSig = string | null; + +/** + * @alpha + */ +export interface IQuicksignResponse { + commandSigData: IQuicksignResponseCommand; + outcome: + | { + hash: string; + result: 'success'; + } + | { + msg: string; + result: 'failure'; + } + | { + result: 'noSig'; + }; +} + +/** + * @alpha + */ +export interface IQuicksignError { + error: + | { + type: 'reject'; + } + | { + type: 'emptyList'; + } + | { + type: 'other'; + msg: string; + }; +} + +/** + * @alpha + */ +export interface IQuicksignResponseCommand { + sigs: IQuicksignSigner[]; + cmd: string; +} diff --git a/packages/libs/client/src/chainweaver-api/v1/sign.ts b/packages/libs/client/src/signing-api/v1/sign.ts similarity index 100% rename from packages/libs/client/src/chainweaver-api/v1/sign.ts rename to packages/libs/client/src/signing-api/v1/sign.ts diff --git a/packages/libs/client/src/signing/signWithChainweaver.ts b/packages/libs/client/src/signing/signWithChainweaver.ts index d0c7ec5d33..3d2f240564 100644 --- a/packages/libs/client/src/signing/signWithChainweaver.ts +++ b/packages/libs/client/src/signing/signWithChainweaver.ts @@ -1,24 +1,15 @@ -import { IChainweaverResponse } from '../interfaces/IChainweaverResponse'; import { IPactCommand } from '../interfaces/IPactCommand'; -import { IUnsignedChainweaverTransaction } from '../interfaces/IUnsignedTransaction'; import { ICommandBuilder } from '../pact'; +import { + IQuickSignRequestBody, + IQuicksignResponse, + IQuicksignSigner, +} from '../signing-api/v1/quicksign'; import fetch from 'cross-fetch'; import type { Debugger } from 'debug'; import _debug from 'debug'; -/** - * @alpha - */ -export type IChainweaverSig = string; - -/** - * @alpha - */ -export interface IChainweaverQuickSignRequestBody { - cmdSigDatas: IUnsignedChainweaverTransaction[]; -} - const debug: Debugger = _debug('pactjs:signWithChainweaver'); /** @@ -27,7 +18,7 @@ const debug: Debugger = _debug('pactjs:signWithChainweaver'); export async function signWithChainweaver( ...transactions: (IPactCommand & ICommandBuilder>)[] ): Promise<(IPactCommand & ICommandBuilder>)[]> { - const quickSignRequest: IChainweaverQuickSignRequestBody = { + const quickSignRequest: IQuickSignRequestBody = { cmdSigDatas: transactions.map((t) => { const command = t.createCommand(); return { @@ -57,11 +48,13 @@ export async function signWithChainweaver( // response is not JSON when not-ok, that's why we use try-catch try { const result = JSON.parse(bodyText) as { - responses: IChainweaverResponse[]; + responses: IQuicksignResponse[]; }; result.responses.map((signedCommand, i) => { - transactions[i].addSignatures(...signedCommand.commandSigData.sigs); + transactions[i].addSignatures( + ...signedCommand.commandSigData.sigs.filter(isASigner), + ); }); return transactions; @@ -75,3 +68,15 @@ export async function signWithChainweaver( ); } } + +function isASigner(signer: IQuicksignSigner): signer is { + pubKey: string; + sig: string; +} { + return ( + 'pubKey' in signer && + 'sig' in signer && + signer.sig !== null && + signer.pubKey.length > 0 + ); +} diff --git a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts index 0e89c77271..ae7ec704c4 100644 --- a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts +++ b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts @@ -4,9 +4,9 @@ jest.mock('cross-fetch', () => { default: jest.fn(), }; }); -import { IChainweaverResponse } from '../../interfaces/IChainweaverResponse'; import { IPactCommand } from '../../interfaces/IPactCommand'; import { ICommandBuilder, Pact } from '../../pact'; +import { IQuicksignResponse } from '../../signing-api/v1/quicksign'; import { signWithChainweaver } from '../signWithChainweaver'; import fetch from 'cross-fetch'; @@ -77,7 +77,7 @@ describe('signWithChainweaver', () => { }); it('adds signatures in multisig fashion to the transactions', async () => { - const mockedResponse: { responses: IChainweaverResponse[] } = { + const mockedResponse: { responses: IQuicksignResponse[] } = { responses: [ { commandSigData: { @@ -114,7 +114,7 @@ describe('signWithChainweaver', () => { expect(unsignedCommand.sigs).toEqual([{ sig: 'gas-key-sig' }, undefined]); // set a new mock response for the second signature - const mockedResponse2: { responses: IChainweaverResponse[] } = { + const mockedResponse2: { responses: IQuicksignResponse[] } = { responses: [ { commandSigData: { @@ -143,7 +143,7 @@ describe('signWithChainweaver', () => { }); it('Wallet signs but does not have the signer key and returns sig null', async () => { - const mockedResponse: { responses: IChainweaverResponse[] } = { + const mockedResponse: { responses: IQuicksignResponse[] } = { responses: [ { commandSigData: { diff --git a/packages/libs/client/src/tests/pact.test.ts b/packages/libs/client/src/tests/pact.test.ts index 83069afa4f..4f5d71a1b2 100644 --- a/packages/libs/client/src/tests/pact.test.ts +++ b/packages/libs/client/src/tests/pact.test.ts @@ -4,7 +4,7 @@ jest.mock('cross-fetch', () => { default: jest.fn(), }; }); -import { IUnsignedTransaction } from '../interfaces/IUnsignedTransaction'; +import { IUnsignedTransaction } from '../interfaces/IPactCommand'; import { ICommandBuilder, Pact, PactCommand } from '../pact'; import fetch from 'cross-fetch'; diff --git a/packages/libs/types/src/PactAPI.ts b/packages/libs/types/src/PactAPI.ts index 6a98b57984..96a2a9d777 100644 --- a/packages/libs/types/src/PactAPI.ts +++ b/packages/libs/types/src/PactAPI.ts @@ -33,10 +33,12 @@ export interface ISendRequestBody { * @alpha */ export type SendResponse = IRequestKeys; + /** * @alpha */ export type LocalRequestBody = ICommand; + /** * @alpha */ diff --git a/packages/libs/types/src/PactCommand.ts b/packages/libs/types/src/PactCommand.ts index 0f9846c44a..19b8a506b8 100644 --- a/packages/libs/types/src/PactCommand.ts +++ b/packages/libs/types/src/PactCommand.ts @@ -208,7 +208,12 @@ export interface IUserSig { export interface ICommand { cmd: CommandPayloadStringifiedJSON; hash: PactTransactionHash; - sigs: Array; + sigs: Array; +} + +export interface ISignatureJson { + // eslint-disable-next-line @rushstack/no-new-null + sig: string | null; } interface IPactResultSuccess { diff --git a/packages/libs/types/src/SignCommand.ts b/packages/libs/types/src/SignCommand.ts index 6e0b2b1ec5..5e20789acd 100644 --- a/packages/libs/types/src/SignCommand.ts +++ b/packages/libs/types/src/SignCommand.ts @@ -2,8 +2,7 @@ * @alpha */ export interface ISignature { - // eslint-disable-next-line @rushstack/no-new-null - sig: string | undefined | null; + sig: string | undefined; } /** From 5c6a6b988344b61b3042bc72a9d9df73064c1b8c Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Fri, 24 Feb 2023 19:17:12 +0900 Subject: [PATCH 16/35] fix ISignature to non-null and use ISignatureJson --- common/config/rush/pnpm-lock.yaml | 2 ++ .../chainweb-node-client/src/tests/local.test.ts | 2 +- .../chainweb-node-client/src/tests/send.test.ts | 2 +- packages/libs/client/etc/client.api.md | 6 +++--- packages/libs/client/src/pact.ts | 3 ++- packages/libs/client/src/signing-api/v1/sign.ts | 9 +++++++++ packages/libs/kadena.js/src/api/pullSignature.ts | 6 +++--- packages/libs/types/etc/types.api.md | 14 ++++++++++---- packages/libs/types/src/PactCommand.ts | 4 +++- packages/libs/types/src/SignCommand.ts | 6 ++---- 10 files changed, 36 insertions(+), 18 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index ef81eb8805..156a9b7530 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -361,6 +361,7 @@ importers: cross-fetch: ~3.1.5 debug: ~4.3.4 eslint: ^8.15.0 + kadena.js: workspace:* ts-node: ~10.8.2 yaml: ~2.1.1 dependencies: @@ -370,6 +371,7 @@ importers: '@kadena/types': link:../types cross-fetch: 3.1.5 debug: 4.3.4 + kadena.js: link:../kadena.js yaml: 2.1.3 devDependencies: '@kadena-dev/eslint-config': link:../../tools/eslint-config diff --git a/packages/libs/chainweb-node-client/src/tests/local.test.ts b/packages/libs/chainweb-node-client/src/tests/local.test.ts index 9247b169ba..e4cb8a58b0 100644 --- a/packages/libs/chainweb-node-client/src/tests/local.test.ts +++ b/packages/libs/chainweb-node-client/src/tests/local.test.ts @@ -32,7 +32,7 @@ test('/local should return result of tx queried', async () => { const signedCommand1: LocalRequestBody = { cmd: commandStr1, hash: cmdWithOneSignature1.hash, - sigs: [{ sig: cmdWithOneSignature1.sig }], + sigs: [{ sig: cmdWithOneSignature1?.sig || null }], }; const commandResult1: LocalResponse = { diff --git a/packages/libs/chainweb-node-client/src/tests/send.test.ts b/packages/libs/chainweb-node-client/src/tests/send.test.ts index acf48f84cb..6835bf7621 100644 --- a/packages/libs/chainweb-node-client/src/tests/send.test.ts +++ b/packages/libs/chainweb-node-client/src/tests/send.test.ts @@ -27,7 +27,7 @@ test('/send should return request keys of txs submitted', async () => { const signedCommand1: ICommand = { cmd: commandStr, hash: cmdWithOneSignature1.hash, - sigs: [{ sig: cmdWithOneSignature1.sig }], + sigs: [{ sig: cmdWithOneSignature1?.sig || null }], }; const expectedRequestKey1 = signedCommand1.hash; diff --git a/packages/libs/client/etc/client.api.md b/packages/libs/client/etc/client.api.md index 8514d98ce7..666196659a 100644 --- a/packages/libs/client/etc/client.api.md +++ b/packages/libs/client/etc/client.api.md @@ -25,7 +25,7 @@ export function buildUnsignedTransaction(parts: string[], holes: string[], args: // @alpha (undocumented) export function createPactCommandFromTemplate(tpl: IPactCommand): PactCommand; -// @public (undocumented) +// @alpha (undocumented) export interface IChainweaverCap { // (undocumented) args: Array>; @@ -33,7 +33,7 @@ export interface IChainweaverCap { name: string; } -// @public (undocumented) +// @alpha (undocumented) export interface IChainweaverCapElement { // (undocumented) cap: IChainweaverCap; @@ -43,7 +43,7 @@ export interface IChainweaverCapElement { role: string; } -// @public (undocumented) +// @alpha (undocumented) export interface IChainweaverSignBody { // (undocumented) caps: IChainweaverCapElement[]; diff --git a/packages/libs/client/src/pact.ts b/packages/libs/client/src/pact.ts index 61bc4e1e54..a1b24f408c 100644 --- a/packages/libs/client/src/pact.ts +++ b/packages/libs/client/src/pact.ts @@ -214,7 +214,8 @@ export class PactCommand // convert to IUnsignedTransaction const command: ICommand = { hash, - sigs: this.sigs.map((s) => (!s ? { sig: undefined } : s)), + // eslint-disable-next-line @rushstack/no-new-null + sigs: this.sigs.map((s) => ({ sig: s?.sig ?? null })), cmd, }; diff --git a/packages/libs/client/src/signing-api/v1/sign.ts b/packages/libs/client/src/signing-api/v1/sign.ts index ecdbf5678f..d38eb72fa5 100644 --- a/packages/libs/client/src/signing-api/v1/sign.ts +++ b/packages/libs/client/src/signing-api/v1/sign.ts @@ -1,3 +1,6 @@ +/** + * @alpha + */ export interface IChainweaverSignBody { code: string; caps: IChainweaverCapElement[]; @@ -11,12 +14,18 @@ export interface IChainweaverSignBody { networkId: string; } +/** + * @alpha + */ export interface IChainweaverCapElement { role: string; description: string; cap: IChainweaverCap; } +/** + * @alpha + */ export interface IChainweaverCap { name: string; args: Array>; diff --git a/packages/libs/kadena.js/src/api/pullSignature.ts b/packages/libs/kadena.js/src/api/pullSignature.ts index 079df6b5c4..d983649ff7 100644 --- a/packages/libs/kadena.js/src/api/pullSignature.ts +++ b/packages/libs/kadena.js/src/api/pullSignature.ts @@ -1,5 +1,5 @@ -import type { ISignature, SignatureWithHash } from '@kadena/types'; +import type { ISignatureJson, SignatureWithHash } from '@kadena/types'; -export function pullSignature({ sig }: SignatureWithHash): ISignature { - return { sig: sig }; +export function pullSignature({ sig }: SignatureWithHash): ISignatureJson { + return { sig: sig ?? null }; } diff --git a/packages/libs/types/etc/types.api.md b/packages/libs/types/etc/types.api.md index 7f9c53af48..fdfb437427 100644 --- a/packages/libs/types/etc/types.api.md +++ b/packages/libs/types/etc/types.api.md @@ -40,7 +40,7 @@ export interface ICommand { // (undocumented) hash: PactTransactionHash; // (undocumented) - sigs: Array; + sigs: Array; } // @alpha @@ -210,7 +210,13 @@ export interface ISendRequestBody { // @alpha (undocumented) export interface ISignature { // (undocumented) - sig: string | undefined | null; + sig: string | undefined; +} + +// @alpha (undocumented) +export interface ISignatureJson { + // (undocumented) + sig: string | null; } // @alpha (undocumented) @@ -230,7 +236,7 @@ export interface ISignedSignatureWithHash extends ISignature { // (undocumented) pubKey: string; // (undocumented) - sig: string | undefined | null; + sig: string | undefined; } // @alpha @@ -270,7 +276,7 @@ export interface IUnsignedSignatureWithHash extends ISignature { // (undocumented) pubKey?: string; // (undocumented) - sig: string | undefined | null; + sig: string | undefined; } // @alpha (undocumented) diff --git a/packages/libs/types/src/PactCommand.ts b/packages/libs/types/src/PactCommand.ts index 19b8a506b8..269676cc05 100644 --- a/packages/libs/types/src/PactCommand.ts +++ b/packages/libs/types/src/PactCommand.ts @@ -1,7 +1,6 @@ import type { Base16String } from './Base16String'; import type { IBase64Url } from './Base64Url'; import type { PactValue } from './PactValue'; -import type { ISignature } from './SignCommand'; /** * A Chainweb transaction payload that executes arbitraty Pact code. * @@ -211,6 +210,9 @@ export interface ICommand { sigs: Array; } +/** + * @alpha + */ export interface ISignatureJson { // eslint-disable-next-line @rushstack/no-new-null sig: string | null; diff --git a/packages/libs/types/src/SignCommand.ts b/packages/libs/types/src/SignCommand.ts index 5e20789acd..5307e305c5 100644 --- a/packages/libs/types/src/SignCommand.ts +++ b/packages/libs/types/src/SignCommand.ts @@ -10,8 +10,7 @@ export interface ISignature { */ export interface ISignedSignatureWithHash extends ISignature { hash: string; - // eslint-disable-next-line @rushstack/no-new-null - sig: string | undefined | null; + sig: string | undefined; pubKey: string; } @@ -20,8 +19,7 @@ export interface ISignedSignatureWithHash extends ISignature { */ export interface IUnsignedSignatureWithHash extends ISignature { hash: string; - // eslint-disable-next-line @rushstack/no-new-null - sig: string | undefined | null; + sig: string | undefined; pubKey?: string; } From 32e259b70e39acf3856040e853bc51ea0292d7fb Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Fri, 24 Feb 2023 19:21:23 +0900 Subject: [PATCH 17/35] rush change --- .../fix-update-quicksign_2023-02-24-10-17.json | 10 ++++++++++ .../fix-update-quicksign_2023-02-24-10-21.json | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 common/changes/@kadena/chainweb-node-client/fix-update-quicksign_2023-02-24-10-17.json create mode 100644 common/changes/@kadena/chainweb-node-client/fix-update-quicksign_2023-02-24-10-21.json diff --git a/common/changes/@kadena/chainweb-node-client/fix-update-quicksign_2023-02-24-10-17.json b/common/changes/@kadena/chainweb-node-client/fix-update-quicksign_2023-02-24-10-17.json new file mode 100644 index 0000000000..4d7142db23 --- /dev/null +++ b/common/changes/@kadena/chainweb-node-client/fix-update-quicksign_2023-02-24-10-17.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@kadena/chainweb-node-client", + "comment": "update ISignature to non-null ", + "type": "patch" + } + ], + "packageName": "@kadena/chainweb-node-client" +} \ No newline at end of file diff --git a/common/changes/@kadena/chainweb-node-client/fix-update-quicksign_2023-02-24-10-21.json b/common/changes/@kadena/chainweb-node-client/fix-update-quicksign_2023-02-24-10-21.json new file mode 100644 index 0000000000..c7ff869291 --- /dev/null +++ b/common/changes/@kadena/chainweb-node-client/fix-update-quicksign_2023-02-24-10-21.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@kadena/chainweb-node-client", + "comment": "", + "type": "none" + } + ], + "packageName": "@kadena/chainweb-node-client" +} \ No newline at end of file From eb60fb349a8c80113159d51aa6dcfebbcf40bfe8 Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Fri, 24 Feb 2023 19:40:25 +0900 Subject: [PATCH 18/35] remove open-api generatioin --- packages/libs/chainweb-node-client/package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/libs/chainweb-node-client/package.json b/packages/libs/chainweb-node-client/package.json index c96de834c4..40e458d853 100644 --- a/packages/libs/chainweb-node-client/package.json +++ b/packages/libs/chainweb-node-client/package.json @@ -28,9 +28,6 @@ "_phase:build": "heft build --clean", "_phase:test": "heft test --no-build", "build": "heft build --clean", - "generate:chainweb:client": "openapi-typescript ./openapi/chainweb.json --output ./src/openapi/chainweb.ts", - "generate:pact:client": "openapi-typescript ./openapi/pact.json --output ./src/openapi/pact.ts", - "postinstall": "npm run generate:pact:client && npm run generate:chainweb:client", "lint": "npx eslint ./src --ext .js,.ts --fix", "test": "rushx build && heft test --no-build" }, From 06fb4902785bef4738d5984f7f9de50f0f9d8886 Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Fri, 24 Feb 2023 20:05:25 +0900 Subject: [PATCH 19/35] add open-api --- .../libs/chainweb-node-client/.eslintignore | 1 + .../libs/chainweb-node-client/package.json | 3 + .../src/openapi/chainweb.ts | 2087 +++++++++++++++++ .../chainweb-node-client/src/openapi/pact.ts | 629 +++++ .../client/src/signing/signWithChainweaver.ts | 6 + 5 files changed, 2726 insertions(+) create mode 100644 packages/libs/chainweb-node-client/.eslintignore create mode 100644 packages/libs/chainweb-node-client/src/openapi/chainweb.ts create mode 100644 packages/libs/chainweb-node-client/src/openapi/pact.ts diff --git a/packages/libs/chainweb-node-client/.eslintignore b/packages/libs/chainweb-node-client/.eslintignore new file mode 100644 index 0000000000..93cad5cf0f --- /dev/null +++ b/packages/libs/chainweb-node-client/.eslintignore @@ -0,0 +1 @@ +/src/openapi/ diff --git a/packages/libs/chainweb-node-client/package.json b/packages/libs/chainweb-node-client/package.json index 40e458d853..c96de834c4 100644 --- a/packages/libs/chainweb-node-client/package.json +++ b/packages/libs/chainweb-node-client/package.json @@ -28,6 +28,9 @@ "_phase:build": "heft build --clean", "_phase:test": "heft test --no-build", "build": "heft build --clean", + "generate:chainweb:client": "openapi-typescript ./openapi/chainweb.json --output ./src/openapi/chainweb.ts", + "generate:pact:client": "openapi-typescript ./openapi/pact.json --output ./src/openapi/pact.ts", + "postinstall": "npm run generate:pact:client && npm run generate:chainweb:client", "lint": "npx eslint ./src --ext .js,.ts --fix", "test": "rushx build && heft test --no-build" }, diff --git a/packages/libs/chainweb-node-client/src/openapi/chainweb.ts b/packages/libs/chainweb-node-client/src/openapi/chainweb.ts new file mode 100644 index 0000000000..3e33b0ab65 --- /dev/null +++ b/packages/libs/chainweb-node-client/src/openapi/chainweb.ts @@ -0,0 +1,2087 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + '/cut': { + /** Query the current cut */ + get: { + /** Query the current cut */ + parameters?: { + /** @description Maximum cut height of the returned cut */ + query?: { + maxheight?: number; + }; + }; + responses: { + /** @description The current cut */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': components['schemas']['cut']; + }; + }; + }; + }; + /** + * Publish a cut + * @description Publish a cut to a Chainweb node. + * + * The cut must contain an origin property that is not `null`. The receiving node + * will first try to obtain all missing dependencies from the node that is + * indicated in by the origin property before searching for the dependencies in the + * P2P network. + */ + put: { + /** + * Publish a cut + * @description Publish a cut to a Chainweb node. + * + * The cut must contain an origin property that is not `null`. The receiving node + * will first try to obtain all missing dependencies from the node that is + * indicated in by the origin property before searching for the dependencies in the + * P2P network. + */ + /** @description A cut with an origin property that is not `null`. */ + requestBody: { + content: { + /** + * @example { + * "value": { + * "origin": null, + * "height": 30798466, + * "weight": "b0wYplmNiTBXCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + * "hashes": { + * "0": { + * "height": 1539923, + * "hash": "qEaSmWt_tDcJC9AGbgWY9x12LW5VED7hGgfyz9x_S3w" + * }, + * "1": { + * "height": 1539923, + * "hash": "TJuC6nfhamfD517gspAZmqD9umR71nAgttDOi1JbBHw" + * }, + * "2": { + * "height": 1539924, + * "hash": "4ineCWfnO1rneWuBMLPzqTl2HF_sZpypT_3TEzf3VLc" + * }, + * "3": { + * "height": 1539924, + * "hash": "ZEOMXB2ByqzL2HfYVKIZKAnoe4wIeJ2SaltnXDir59k" + * }, + * "4": { + * "height": 1539923, + * "hash": "0g0rOoSznVW2BJDBmK0Lbxz22F-sxTZUNIrUs_Q8Ye4" + * }, + * "5": { + * "height": 1539923, + * "hash": "5y_TL-clnF_wELMBKyJk0Sz8RVShw_bGQETJdrMkADA" + * }, + * "6": { + * "height": 1539923, + * "hash": "YkQKv6P4_C4jRM3RqKK9FWPxIneeLzlkKQS9ATAQYRk" + * }, + * "7": { + * "height": 1539923, + * "hash": "j_hJ9iiH_ATyeQeeRN3auGXjbBWiFgnTU0dYPIz8cKM" + * }, + * "8": { + * "height": 1539924, + * "hash": "s7c3B55VbDsS6EJ-nc9S5k2kNbPOBGI8xxF3vUg4d4Q" + * }, + * "9": { + * "height": 1539922, + * "hash": "bowQf63xSY9owHKhK1yGee2Q0Fn8yL_oCLaEUn-CGoA" + * }, + * "10": { + * "height": 1539924, + * "hash": "uP-pHW4QKrV9fN1mlDGwKuaiIDlJW7xYSj1nW53EHM4" + * }, + * "11": { + * "height": 1539924, + * "hash": "TIhegjZ0GEC73T4m0BVuFtfLNGuS56IUWEuf93AJ5UU" + * }, + * "12": { + * "height": 1539923, + * "hash": "-j1qcAS9Fs-WQmc3WEhzZ96VojxnlIA2TFpfyIv31Zs" + * }, + * "13": { + * "height": 1539923, + * "hash": "S-4TqMgWGlK1k33XRlU9w0Lfwr0RvkO5Jn78Au1OglM" + * }, + * "14": { + * "height": 1539923, + * "hash": "xSuULf--S4TrgYNz82deaGhnPLWrg3pXkynGeUPUGwA" + * }, + * "15": { + * "height": 1539923, + * "hash": "jsc9rugvcHXDiBAuoO9_j8R_b_jchtJJ8b5596i8wVg" + * }, + * "16": { + * "height": 1539923, + * "hash": "qs1aEY8kSxfUBb_JRVswv5dYINRXBjGJteC-6RC1hjc" + * }, + * "17": { + * "height": 1539924, + * "hash": "xzVBXaQxzlUfUrakDgppUubQBRXGh-Uy0HBdMNwCq_Y" + * }, + * "18": { + * "height": 1539924, + * "hash": "4VOHPAqwioySYRycdl5MxfscQHwtlwwCAt7AySYQT98" + * }, + * "19": { + * "height": 1539923, + * "hash": "1PrRg20XyQ_2cfgGOgNK9K-cqIJ1vO8-A-RJlfN5m00" + * } + * }, + * "id": "BBz7KeurYTeQ0hMGbwUbQC84cRbVcacoDQTye-3qkXI", + * "instance": "mainnet01" + * } + * } + */ + 'application/json': components['schemas']['cut'] & + Record; + }; + }; + responses: { + /** @description The cut was added to the cut processing pipeline of the remote node */ + 204: never; + /** @description The requester is not a peer of this node, and thus not allowed to send it cuts */ + 401: never; + }; + }; + }; + '/cut/peer': { + /** Get Cut-Network Peer Info */ + get: { + /** Get Cut-Network Peer Info */ + responses: { + /** @description Peers from the peer database of the remote node */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + /** @description Array of peers */ + items?: Record; + } & components['schemas']['page']; + }; + }; + }; + }; + /** Put Cut-Network Peer Info */ + put: { + /** Put Cut-Network Peer Info */ + /** + * @description The peer that is added to the peer database of the cut P2P network of + * the remote host. + */ + requestBody?: { + content: { + 'application/json': components['schemas']['peer'] & { + id?: Record | null; + }; + }; + }; + responses: { + /** @description The peer got added to the peer database of the remote node. */ + 204: never; + /** + * @description The request is invalid. It is either malformed or the provided peer + * is not reachable. + * + * Before the remote node adds a peer to its peer database it checks + * whether the peer can be reached via the provided address. If this + * check fails an error is returned. + */ + 400: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'text/plain': unknown; + }; + }; + }; + }; + }; + '/chain/{chain}/hash': { + /** Get Block Hashes */ + get: { + /** Get Block Hashes */ + responses: { + /** + * @description A page of a collection of block hashes in **ascending** order + * that satisfies query parameters. Any block hash from the chain + * database is returned. **This includes hashes of orphaned blocks.** + */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + /** @description Array of block hashes */ + items?: Record; + } & components['schemas']['page']; + }; + }; + /** @description A parameter indicated a nonexistent block height. */ + 404: { + content: { + 'application/json': { + reason?: string; + key?: components['schemas']['blockHash']; + }; + }; + }; + }; + }; + }; + '/chain/{chain}/hash/branch': { + /** + * Get Block Hash Branches + * @description A page of block hashes from branches of the block chain in + * **descending** order. + * + * Only blocks are returned that are ancestors of the some block in the + * set of upper bounds and are not ancestors of any block in the set of + * lower bounds. + */ + post: { + /** + * Get Block Hash Branches + * @description A page of block hashes from branches of the block chain in + * **descending** order. + * + * Only blocks are returned that are ancestors of the some block in the + * set of upper bounds and are not ancestors of any block in the set of + * lower bounds. + */ + /** @description Upper and lower bounds of the queried branches */ + requestBody?: { + content: { + 'application/json': { + /** + * @description No block hashes are returned that are predecessors of any + * block with a hash from this array. + */ + lower?: components['schemas']['blockHash'][]; + /** + * @description Returned block hashes are predecessors of a block with an + * hash from this array. This includes blocks with hashes from + * this array. + */ + upper?: components['schemas']['blockHash'][]; + }; + }; + }; + responses: { + /** @description The requested block hashes */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + /** @description Array of block hashes */ + items?: Record; + } & components['schemas']['page']; + }; + }; + /** @description The requested block hashes could not be found */ + 404: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + reason?: string; + key?: components['schemas']['blockHash']; + }; + }; + }; + }; + }; + }; + '/chain/{chain}/header': { + /** + * Get Block Headers + * @description A page of a collection of block headers in **ascending** order + * that satisfies query parameters. Any block header from the chain + * database is returned. **This includes headers of orphaned blocks.** + */ + get: { + /** + * Get Block Headers + * @description A page of a collection of block headers in **ascending** order + * that satisfies query parameters. Any block header from the chain + * database is returned. **This includes headers of orphaned blocks.** + */ + responses: { + /** @description The requested block headers */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + /** @description Array of base64 encoded block headers */ + items?: components['schemas']['base64Header'][]; + } & components['schemas']['page']; + 'application/json;blockheader-encoding=object': { + /** @description Array of JSON encoded block headers */ + items?: Record; + } & components['schemas']['page']; + }; + }; + /** @description The `next` or `maxheight` parameter indicated a nonexistent block height. */ + 404: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + reason?: string; + key?: components['schemas']['blockHash']; + }; + }; + }; + }; + }; + }; + '/chain/{chain}/header/{blockHash}': { + /** + * Get Block Header by Hash + * @description Query a block header by its hash + */ + get: { + /** + * Get Block Header by Hash + * @description Query a block header by its hash + */ + responses: { + /** @description The block header with that hash was found */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': components['schemas']['base64Header']; + 'application/json;blockheader-encoding=object': components['schemas']['blockHeader']; + 'application/octet-stream': components['schemas']['binaryHeader']; + }; + }; + /** @description A block header with that block hash was not found. */ + 404: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + reason?: string; + key?: components['schemas']['blockHash']; + }; + }; + }; + /** @description The value of the `Accept` header is not supported. */ + 406: never; + }; + }; + }; + '/chain/{chain}/header/branch': { + /** + * Get Block Header Branches + * @description A page of block headers from branches of the block chain in + * **descending** order. + * + * Only blocks are returned that are ancestors of the some block in the + * set of upper bounds and are not ancestors of any block in the set of + * lower bounds. + */ + post: { + /** + * Get Block Header Branches + * @description A page of block headers from branches of the block chain in + * **descending** order. + * + * Only blocks are returned that are ancestors of the some block in the + * set of upper bounds and are not ancestors of any block in the set of + * lower bounds. + */ + /** @description Upper and lower bounds of the queried branches */ + requestBody?: { + content: { + 'application/json': { + /** + * @description No blocks are returned that are predecessors of any block with + * an hash from this array. + */ + lower?: components['schemas']['blockHash'][]; + /** + * @description Returned block headers are predecessors of a block with an + * hash from this array. This includes blocks with hashes from + * this array. + */ + upper?: components['schemas']['blockHash'][]; + }; + }; + }; + responses: { + /** @description The block headers were found */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + /** @description Array of base64 encoded block headers */ + items?: Record; + } & components['schemas']['page']; + 'application/json;blockheader-encoding=object': { + /** @description Array of JSON encoded block headers */ + items?: Record; + } & components['schemas']['page']; + }; + }; + /** @description A block header indicated by a required parameter was not found. */ + 404: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + reason?: string; + key?: components['schemas']['blockHash']; + }; + }; + }; + /** @description The value of the `Accept` header is not supported. */ + 406: never; + }; + }; + }; + '/chain/{chain}/payload/{payloadHash}': { + /** Get Block Payload */ + get: { + /** Get Block Payload */ + responses: { + /** @description The payload data of for the given block payload hash */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': components['schemas']['payload']; + }; + }; + /** @description The block payload with that hash was not found */ + 404: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + /** @description Failure message */ + reason?: string; + key?: components['schemas']['payloadHash']; + }; + }; + }; + }; + }; + }; + '/chain/{chain}/payload/batch': { + /** Get Batch of Block Payload */ + post: { + /** Get Batch of Block Payload */ + requestBody: components['requestBodies']['payloadHashArray']; + responses: { + /** + * @description Array of the some or all of the requested block payloads. The + * payloads may be returned in any order. + */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': components['schemas']['payload'][]; + }; + }; + }; + }; + }; + '/chain/{chain}/payload/{payloadHash}/outputs': { + /** Get Block Payload With Outputs */ + get: { + /** Get Block Payload With Outputs */ + responses: { + /** @description The payload with outputs for the given block payload hash */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': components['schemas']['payloadWithOutputs']; + }; + }; + /** @description A block payload with that hash was not found */ + 404: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + /** @description Failure message */ + reason?: string; + key?: components['schemas']['payloadHash']; + }; + }; + }; + }; + }; + }; + '/chain/{chain}/payload/outputs/batch': { + /** Get Batch of Block Payload With Outputs */ + post: { + /** Get Batch of Block Payload With Outputs */ + requestBody: components['requestBodies']['payloadHashArray']; + responses: { + /** + * @description Array of the some or all of the requested block payloads with + * outputs. Result items maybe returned in any order. + */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': components['schemas']['payloadWithOutputs'][]; + }; + }; + }; + }; + }; + '/chain/{chain}/mempool/getPending': { + /** Get Pending Transactions from the Mempool */ + post: { + /** Get Pending Transactions from the Mempool */ + parameters?: { + /** @description Server nonce value */ + /** @description Mempool tx id value */ + query?: { + nonce?: number; + since?: number; + }; + }; + responses: { + /** @description recent state of pending transactions in the mempool */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + hashes?: string[]; + /** @description two-element array: `[nonce (integer), since (int64)]` */ + highwaterMark?: number[]; + }; + }; + }; + }; + }; + }; + '/chain/{chain}/mempool/member': { + /** Check for Pending Transactions in the Mempool */ + post: { + /** Check for Pending Transactions in the Mempool */ + requestBody: components['requestBodies']['requestKeyArray']; + responses: { + /** + * @description Array of boolean values that indicate whether the respective + * transaction is in the mempool. + * + * The array has the same size as the request body. + */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': boolean[]; + }; + }; + }; + }; + }; + '/chain/{chain}/mempool/lookup': { + /** Lookup Pending Transactions in the Mempool */ + post: { + /** Lookup Pending Transactions in the Mempool */ + requestBody: components['requestBodies']['requestKeyArray']; + responses: { + /** @description Array of lookup results for the respective transactions */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + /** @enum {string} */ + tag?: 'Missing' | 'Pending'; + contents?: components['schemas']['signedTxText']; + }[]; + }; + }; + }; + }; + }; + '/chain/{chain}/mempool/insert': { + /** Insert Transactions into the Mempool */ + put: { + /** Insert Transactions into the Mempool */ + /** @description Array of strings of JSON encoded signed transactions */ + requestBody?: { + content: { + 'application/json': components['schemas']['signedTxText'][]; + }; + }; + responses: { + /** @description Transactions were inserted */ + 200: never; + }; + }; + }; + '/chain/{chain}/mempool/peer': { + /** Get Chain Mempool-Network Peer Info */ + get: { + /** Get Chain Mempool-Network Peer Info */ + responses: { + /** @description Peer information */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': { + /** @description Array of peers */ + items?: Record; + } & components['schemas']['page']; + }; + }; + }; + }; + /** Put Chain Mempool-Network Peer Info */ + put: { + /** Put Chain Mempool-Network Peer Info */ + /** + * @description The peer that is added to the peer database of the mempoo P2P network of + * the chain `{chain}` of remote host. + */ + requestBody?: { + content: { + 'application/json': components['schemas']['peer'] & { + id?: Record | null; + }; + }; + }; + responses: { + /** @description The peer got added to the peer database of the remote node. */ + 204: never; + /** + * @description Bad Request. + * The request is invalid. It is either malformed or the provided peer is not reachable. + * + * Before the remote node addes a peer to its peer database it checks whether the peer can be reached + * via the provided address. If this check fails an error is returned. + */ + 400: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'text/plain': unknown; + }; + }; + }; + }; + }; + '/mining/work': { + /** + * Get Mining Work + * @description A new BlockHeader to mine on + */ + get: { + /** + * Get Mining Work + * @description A new BlockHeader to mine on + */ + /** @description Miner Info */ + requestBody?: { + content: { + /** + * @example { + * "account": "miner", + * "predicate": "keys-all", + * "public-keys": [ + * "f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27" + * ] + * } + */ + 'application/json': components['schemas']['minerInfo']; + }; + }; + responses: { + /** @description A mining work item */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/octet-stream': { + /** + * 4 Chain ID Bytes + * Format: binary + * @description The chain selection made by the Node. This is + * informational. Generally, miner should not care about the + * chain. + */ + chainBytes?: string; + /** + * 32 PoW Target Bytes + * Format: binary + * @description The PoW target for the current block. The PoW hash of a + * valid block must not be larger than this value. + * + * For arithmetic comparisons the hash-target and the PoW + * hash are interpreted as unsigned 256 bit integral number + * in little endian encoding. + */ + targetBytes?: string; + /** + * 286 Work Header Bytes + * Format: binary + * @description PoW Work Header Bytes. The last 8 bytes are the nonce. The + * creation time is encoded in bytes 44-52. Miners must not + * change or make any assumption about the other bytes. + * + * The creation time is encoded as little endian twoth + * complement integral number that counts SI microseconds + * since POSIX epoch (leap seconds are ignored). It always + * positive (highest bit is 0). Miners are free but not + * required to update the creation time. The value must be + * strictly larger than the creation time of the parent block + * and must not be in the future. + */ + headerBytes?: string; + }; + }; + }; + }; + }; + }; + '/chainweb/0.0/mainnet01/mining/solved': { + /** + * Solved Mining Work + * @description Submit a solution for a new block + */ + post: { + /** + * Solved Mining Work + * @description Submit a solution for a new block + */ + /** @description The solved PoW work header bytes */ + requestBody?: { + content: { + 'application/octet-stream': string; + }; + }; + responses: { + /** @description Solved mining work is valid */ + 204: never; + }; + }; + }; + '/mining/updates': { + /** + * Notification of Updated Work + * @description An server-sent event sources that notifies miners when new mining + * work becomes available. + * + * The stream is terminated by the server in regular intervals and + * it is up to the client to request a new stream. + */ + get: { + /** + * Notification of Updated Work + * @description An server-sent event sources that notifies miners when new mining + * work becomes available. + * + * The stream is terminated by the server in regular intervals and + * it is up to the client to request a new stream. + */ + /** @description The first 4 bytes received from a call to `/mining/work`. This tells the Node to only inform the Miner of a new Cut when the specific chain in question has updated. */ + requestBody?: { + content: { + 'application/octet-stream': string; + }; + }; + responses: { + /** + * @description Each events consists of a single line: `event:New Cut`. + * Events are separated by empty lines. + */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'text/event-stream': components['schemas']['miningUpdateEventStream']; + }; + }; + }; + }; + }; + '/config': { + /** + * Configuration of Chainweb Node + * @description Returns the configuration of chainweb-node as a JSON structure. + * Sensitive information is removed from the result. The JSON schema depends + * on the chainweb node version and is not part of the stable chainweb-node + * API. + */ + get: { + /** + * Configuration of Chainweb Node + * @description Returns the configuration of chainweb-node as a JSON structure. + * Sensitive information is removed from the result. The JSON schema depends + * on the chainweb node version and is not part of the stable chainweb-node + * API. + */ + responses: { + /** @description Configuration of the chainweb node */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': unknown; + }; + }; + }; + }; + }; + '/make-backup': { + /** + * Start a backup job + * @description Backup jobs are identified by the Unix timestamp when they're begun. + * + * If a backup job is already in progress, this endpoint will return its + * identifier instead of starting a new one. + * + * The RocksDB portion of the database is always backed up; if backupPact + * is set, the Sqlite (Pact) portion is backed up as well, taking much + * longer. + * + * There is no automatic backup retention policy - users need to delete old + * backups. + * + * This API is enabled by configuring the node thus: + * ```yaml + * backup: + * api: + * enabled: true + * directory: {some file path to put backups in} + * ``` + * The backup directory ideally will be located in the same partition as the + * RocksDB portion of the node database. + * + * RocksDB backups to the same partition as holds the active RocksDB + * database will have almost zero space overhead immediately, but over time + * as the active database diverges from the backup the space overhead will + * increase. If the backup is to another partition, it will take longer + * and take as much disk space as the active RocksDB database. + * + * Pact database backups always require about as much space as the active + * Pact database does. + */ + post: { + /** + * Start a backup job + * @description Backup jobs are identified by the Unix timestamp when they're begun. + * + * If a backup job is already in progress, this endpoint will return its + * identifier instead of starting a new one. + * + * The RocksDB portion of the database is always backed up; if backupPact + * is set, the Sqlite (Pact) portion is backed up as well, taking much + * longer. + * + * There is no automatic backup retention policy - users need to delete old + * backups. + * + * This API is enabled by configuring the node thus: + * ```yaml + * backup: + * api: + * enabled: true + * directory: {some file path to put backups in} + * ``` + * The backup directory ideally will be located in the same partition as the + * RocksDB portion of the node database. + * + * RocksDB backups to the same partition as holds the active RocksDB + * database will have almost zero space overhead immediately, but over time + * as the active database diverges from the backup the space overhead will + * increase. If the backup is to another partition, it will take longer + * and take as much disk space as the active RocksDB database. + * + * Pact database backups always require about as much space as the active + * Pact database does. + */ + responses: { + /** @description A backup job has been created */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'text/plain': components['schemas']['backupId']; + }; + }; + }; + }; + }; + '/check-backup/{backupId}': { + /** Check the status of a backup job */ + get: { + /** Check the status of a backup job */ + responses: { + /** @description A backup job with that identifier exists, here is its status */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'text/plain': components['schemas']['backupStatus']; + }; + }; + /** @description There is no backup job with that identifier */ + 404: never; + }; + }; + }; + '/health-check': { + /** + * Health Check + * @description Checks whether the chainweb-node is up and running and responding to API + * requests. In order to check the state of consensus the + * [/cut/get](#tag/cut/paths/~1cut/get) endpoint should be used instead. + */ + get: { + /** + * Health Check + * @description Checks whether the chainweb-node is up and running and responding to API + * requests. In order to check the state of consensus the + * [/cut/get](#tag/cut/paths/~1cut/get) endpoint should be used instead. + */ + responses: { + /** @description The node is healthy */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'text/plain': string; + }; + }; + }; + }; + }; + '/info': { + /** + * General Node Info + * @description Provides general information about the node and the chainweb version + */ + get: { + /** + * General Node Info + * @description Provides general information about the node and the chainweb version + */ + responses: { + /** @description General information about the node and the chainweb version */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'application/json': components['schemas']['nodeInfo']; + }; + }; + }; + }; + }; + '/header/updates': { + /** + * Blocks Event Stream + * @description An source of server events that emits a `BlockHeader` event for each new + * block header that is added to the chain database of the remote node. + * + * The stream contains blocks that may later become orphaned. It is + * therefor recommended to buffer events on the client side for the most + * recent block heights until the desired confirmation depth is reached. + * + * The server may terminate this stream from time to time and it is up to + * the client to reinitiate the stream. + */ + get: { + /** + * Blocks Event Stream + * @description An source of server events that emits a `BlockHeader` event for each new + * block header that is added to the chain database of the remote node. + * + * The stream contains blocks that may later become orphaned. It is + * therefor recommended to buffer events on the client side for the most + * recent block heights until the desired confirmation depth is reached. + * + * The server may terminate this stream from time to time and it is up to + * the client to reinitiate the stream. + */ + responses: { + /** + * @description A stream of `BlockHeader` events. **This is not a JSON array**. + * + * Events are separated by empty lines. Each event consists of an + * `event` property and a `data` property which are separated by + * newlines. + */ + 200: { + headers: { + 'x-peer-addr': components['headers']['x-peer-addr']; + 'x-server-timestamp': components['headers']['x-server-timestamp']; + 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; + }; + content: { + 'text/event-stream': { + /** @enum {string} */ + event?: 'BlockHeader'; + data?: { + /** @description Number of transactions in the block */ + txCount?: number; + /** @description A custom representation of the POW hash for use in the block explorer UI */ + powHash?: string; + header?: components['schemas']['blockHeader']; + /** @description A custom representation of the POW target for use in the block explorer UI */ + target?: string; + }; + }[]; + }; + }; + }; + }; + }; +} + +export type webhooks = Record; + +export interface components { + schemas: { + /** + * POSIX Timestamp + * @description Seconds since POSIX epoch + * @example 1619108524 + */ + posixTimestamp: number; + /** + * POSIX Timestamp in Microseconds + * @description Microseconds since POSIX epoch + * @example 1602382624629329 + */ + posixTimestampMicro: number; + /** + * Chainweb Version + * @description The version of the Chainweb network + * @enum {unknown} + */ + chainwebVersion: + | 'test-singleton' + | 'development' + | 'mainnet01' + | 'testnet04'; + /** + * Chain ID + * @description A Chainweb chain ID. In Kadena Chainweb chains are named by numbers + * starting form 0. Valid values depend on the current graph at the + * respective block height of the chainweb version. + * + * @example 0 + */ + chainId: number; + /** + * Host Address + * @description Host address containing IPv4 and port + * @example 10.36.1.3:42988 + */ + hostAddress: string; + /** + * Signed Transaction Text + * @description Text of a JSON encoded signed Pact transaction + * @example { + * "value": { + * "hash": "y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw", + * "sigs": [ + * { + * "sig": "8ddc06b37c496f2cadc4f7412405a80faf3ab07482ff5553b9b5fcc73d1b4121275ad5948d9b4078e553b71f8b42eaf6b24135bf2fb4d5840c16bcdde0e35e0f" + * } + * ], + * "cmd": "{\"networkId\":\"mainnet01\",\"payload\":{\"exec\":{\"data\":{\"account-keyset\":{\"pred\":\"keys-all\",\"keys\":[\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\"]}},\"code\":\"(coin.transfer-create \\\"60241f51ea34e05c61fbea9d\\\" \\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\" (read-keyset \\\"account-keyset\\\") 5007.0000)\"}},\"signers\":[{\"pubKey\":\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\",\"clist\":[{\"args\":[\"60241f51ea34e05c61fbea9d\",\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\",5007],\"name\":\"coin.TRANSFER\"},{\"args\":[],\"name\":\"coin.GAS\"}]}],\"meta\":{\"creationTime\":1618949714,\"ttl\":300,\"gasLimit\":600,\"chainId\":\"0\",\"gasPrice\":1.0e-7,\"sender\":\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\"},\"nonce\":\"\\\"2021-04-20T20:16:13.645Z\\\"\"}" + * } + * } + */ + signedTxText: string; + /** + * Request Key + * @description Base64Url-encoded, request key of a Pact transaction + * @example y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw + */ + requestKey: string; + /** + * SHA256 Hash + * @description Base64Url (without padding) encoded SHA256 hash + * @example y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw + */ + sha256Hash: string; + /** + * Block Hash + * @description Base64Url (without padding) encoded block hash + * @example QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH7 + */ + blockHash: components['schemas']['sha256Hash']; + /** + * Block Payload Hash + * @description Base64Url (without padding) encoded block payload hash + * @example GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA + */ + payloadHash: components['schemas']['sha256Hash']; + /** + * Block Height + * @description The height of a block is the number of its predecessors in the block chain + * + * @example 1000000 + */ + blockHeight: number; + /** + * Block Weight + * @description The POW weight of a block is the sum of the difficulties of the block + * and of all of its ancestors. The difficulty of a block is the maximum + * difficulty divided by the target. + * + * It represented as the base64Url (without padding) 256 bit little endian + * encoding of the numerical value. + * + * @example iil_D0t2MGqjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + */ + blockWeight: string; + /** + * PoW Target + * @description The PoW target of a block represented as the base64Url (without + * padding) 256 bit little endian encoding of the numerical value. + * + * @example 2uMCnB4lWsErj9w1C1vAp1sHYd-sABf3kgcAAAAAAAA + */ + target: string; + /** + * PoW Nonce + * @description PoW nonce of the block. This is computed by the miner such that the + * block hash is smaller than the target. + */ + nonce: string; + /** + * Base64Url Block Header + * @description Base64Url (without padding) encoded binary block header + * @example { + * "value": { + * "$ref": "components[\"examples\"][\"base64HeaderPage\"][\"value\"][\"items\"][\"0\"]" + * } + * } + */ + base64Header: string; + /** Backup job status */ + backupStatus: string; + /** + * Backup job identifier + * @description Textual backup job identifier + * @example 1648665437000 + */ + backupId: string; + /** + * Binary Block Header + * @description Binary representation of a block header + */ + binaryHeader: string; + /** + * Block Header + * @description JSON Encoded Block Header + * @example { + * "value": { + * "$ref": "components[\"examples\"][\"blockHeaderPage\"][\"value\"][\"items\"][\"0\"]" + * } + * } + */ + blockHeader: { + creationTime: components['schemas']['posixTimestampMicro']; + parent: components['schemas']['blockHash']; + height: components['schemas']['blockHeight']; + hash: components['schemas']['blockHash']; + chainId: components['schemas']['chainId']; + weight: components['schemas']['blockWeight']; + /** @description A reserved value that must be 0. */ + featureFlags: number; + epochStart: components['schemas']['posixTimestampMicro']; + /** + * @description The block hashes of the adjacent parents of the block. This is + * represented as an associative array that maps the adjancent chain + * ids to the respective block hash. + */ + adjacents: { + [key: string]: components['schemas']['blockHash'] | undefined; + }; + payloadHash: components['schemas']['payloadHash']; + chainwebVersion: components['schemas']['chainwebVersion']; + target: components['schemas']['target']; + nonce: components['schemas']['nonce']; + }; + /** + * Block Payload + * @description Payload of a Block including the Merkle roots for transactions and + * transaction outputs. + * + * @example { + * "value": { + * "$ref": "components[\"examples\"][\"payloads\"][\"value\"][\"1\"]" + * } + * } + */ + payload: { + /** @description Array of base64Url (without padding) encoded JSON texts of signed Pact transactions */ + transactions: string[]; + /** @description Base64Url (without padding) encoded JSON text of the miner data of the payload */ + minerData: string; + transactionsHash: components['schemas']['sha256Hash']; + outputsHash: components['schemas']['sha256Hash']; + payloadHash: components['schemas']['payloadHash']; + }; + /** + * Block Payload With Outputs + * @description Payload with outputs of a Block including the Merkle roots for + * transactions and transaction outputs + * + * @example { + * "value": { + * "transactions": [], + * "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", + * "transactionsHash": "nT0j4xw2woMkdXXaopdurXIn24OG-jNMqQzUGfxV_MA", + * "outputsHash": "4pXRrZ2K0_V0iGAxQCKrKdLjQTBZHBOQS7P-47kdnhY", + * "payloadHash": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA", + * "coinbase": "eyJnYXMiOjAsInJlc3VsdCI6eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6IldyaXRlIHN1Y2NlZWRlZCJ9LCJyZXFLZXkiOiJJa2hoV0VGQ2NURlFTMU5MYkdodVkwcHJNRjlOZERjMVgyeE1OMDVUTTNkSk5qSTNVV1pZV2w4NE5Xc2kiLCJsb2dzIjoiZ3Noak1kWFJrVGxKYmIxalZkQWJ6SVVDcGpQb1JBQ2pEbExzRzBXNkJEMCIsIm1ldGFEYXRhIjpudWxsLCJjb250aW51YXRpb24iOm51bGwsInR4SWQiOjEyNzIzNTB9" + * } + * } + */ + payloadWithOutputs: { + /** + * @description Array of pairs of transactions and their outputs. + * Signed Pact transactions and outputs are base64Url-encoded without padding. + */ + transactions: (string | string)[][]; + /** @description Base64Url (without padding) encoded JSON text of the miner data of the payload */ + minerData: string; + transactionsHash: components['schemas']['sha256Hash']; + outputsHash: components['schemas']['sha256Hash']; + payloadHash: components['schemas']['payloadHash']; + /** @description Base64Url (without padding) encoded JSON text of coinbase output of the block */ + coinbase: string; + }; + /** + * Peer + * @description Peer info object + * @example { + * "address": { + * "hostname": "85.238.99.91", + * "port": 30004 + * }, + * "id": "PRLmVUcc9AH3fyfMYiWeC4nV2i1iHwc0-aM7iAO8h18" + * } + */ + peer: { + /** + * @description The base64Url (without padding) encoded SHA256 fingerprint of the + * SSL certificate of the node. This can be null only if the node uses + * an official CA signed certificate + */ + id: string | null; + address: { + /** + * @description A domain name or IP address. This must be a domain name only if + * the respective node is using a valid CA signed SSL certificate. + */ + hostname: + | Record + | Record + | Record; + /** @description Port number */ + port: number; + }; + }; + /** + * Cut + * @description Cut datastruction of the chainweb API + * @example { + * "value": { + * "origin": null, + * "height": 30798466, + * "weight": "b0wYplmNiTBXCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + * "hashes": { + * "0": { + * "height": 1539923, + * "hash": "qEaSmWt_tDcJC9AGbgWY9x12LW5VED7hGgfyz9x_S3w" + * }, + * "1": { + * "height": 1539923, + * "hash": "TJuC6nfhamfD517gspAZmqD9umR71nAgttDOi1JbBHw" + * }, + * "2": { + * "height": 1539924, + * "hash": "4ineCWfnO1rneWuBMLPzqTl2HF_sZpypT_3TEzf3VLc" + * }, + * "3": { + * "height": 1539924, + * "hash": "ZEOMXB2ByqzL2HfYVKIZKAnoe4wIeJ2SaltnXDir59k" + * }, + * "4": { + * "height": 1539923, + * "hash": "0g0rOoSznVW2BJDBmK0Lbxz22F-sxTZUNIrUs_Q8Ye4" + * }, + * "5": { + * "height": 1539923, + * "hash": "5y_TL-clnF_wELMBKyJk0Sz8RVShw_bGQETJdrMkADA" + * }, + * "6": { + * "height": 1539923, + * "hash": "YkQKv6P4_C4jRM3RqKK9FWPxIneeLzlkKQS9ATAQYRk" + * }, + * "7": { + * "height": 1539923, + * "hash": "j_hJ9iiH_ATyeQeeRN3auGXjbBWiFgnTU0dYPIz8cKM" + * }, + * "8": { + * "height": 1539924, + * "hash": "s7c3B55VbDsS6EJ-nc9S5k2kNbPOBGI8xxF3vUg4d4Q" + * }, + * "9": { + * "height": 1539922, + * "hash": "bowQf63xSY9owHKhK1yGee2Q0Fn8yL_oCLaEUn-CGoA" + * }, + * "10": { + * "height": 1539924, + * "hash": "uP-pHW4QKrV9fN1mlDGwKuaiIDlJW7xYSj1nW53EHM4" + * }, + * "11": { + * "height": 1539924, + * "hash": "TIhegjZ0GEC73T4m0BVuFtfLNGuS56IUWEuf93AJ5UU" + * }, + * "12": { + * "height": 1539923, + * "hash": "-j1qcAS9Fs-WQmc3WEhzZ96VojxnlIA2TFpfyIv31Zs" + * }, + * "13": { + * "height": 1539923, + * "hash": "S-4TqMgWGlK1k33XRlU9w0Lfwr0RvkO5Jn78Au1OglM" + * }, + * "14": { + * "height": 1539923, + * "hash": "xSuULf--S4TrgYNz82deaGhnPLWrg3pXkynGeUPUGwA" + * }, + * "15": { + * "height": 1539923, + * "hash": "jsc9rugvcHXDiBAuoO9_j8R_b_jchtJJ8b5596i8wVg" + * }, + * "16": { + * "height": 1539923, + * "hash": "qs1aEY8kSxfUBb_JRVswv5dYINRXBjGJteC-6RC1hjc" + * }, + * "17": { + * "height": 1539924, + * "hash": "xzVBXaQxzlUfUrakDgppUubQBRXGh-Uy0HBdMNwCq_Y" + * }, + * "18": { + * "height": 1539924, + * "hash": "4VOHPAqwioySYRycdl5MxfscQHwtlwwCAt7AySYQT98" + * }, + * "19": { + * "height": 1539923, + * "hash": "1PrRg20XyQ_2cfgGOgNK9K-cqIJ1vO8-A-RJlfN5m00" + * } + * }, + * "id": "BBz7KeurYTeQ0hMGbwUbQC84cRbVcacoDQTye-3qkXI", + * "instance": "mainnet01" + * } + * } + */ + cut: { + origin?: components['schemas']['peer']; + /** + * @description The cut height is the sum of the height of all blocks of the cut. + * Usage of this value should be avoided, because its semantics may + * change in the future + */ + height: number; + /** @description The sum of the weights of all blocks in the cut */ + weight: string; + /** + * @description An object that maps chain Ids to their respective block hash and + * block height + */ + hashes: { + [key: string]: components['schemas']['hashWithBlockHeight'] | undefined; + }; + instance?: string; + id?: string; + }; + /** + * Hash with block height + * @description A block hash and the height of that block + * @example { + * "height": 1539924, + * "hash": "uP-pHW4QKrV9fN1mlDGwKuaiIDlJW7xYSj1nW53EHM4" + * } + */ + hashWithBlockHeight: { + hash: string; + height: number; + }; + /** + * Chainweb Node Info + * @description General information about a chainweb node + * @example { + * "value": { + * "nodeNumberOfChains": 20, + * "nodeApiVersion": "0.0", + * "nodeChains": [ + * "12", + * "13", + * "14", + * "15", + * "8", + * "9", + * "10", + * "11", + * "4", + * "5", + * "6", + * "7", + * "0", + * "16", + * "1", + * "17", + * "2", + * "18", + * "3", + * "19" + * ], + * "nodeVersion": "mainnet01", + * "nodeGraphHistory": [ + * [ + * 0, + * [ + * [ + * 0, + * [ + * 5, + * 2, + * 3 + * ] + * ], + * [ + * 1, + * [ + * 4, + * 6, + * 3 + * ] + * ], + * [ + * 2, + * [ + * 4, + * 7, + * 0 + * ] + * ], + * [ + * 3, + * [ + * 8, + * 0, + * 1 + * ] + * ], + * [ + * 4, + * [ + * 9, + * 1, + * 2 + * ] + * ], + * [ + * 5, + * [ + * 9, + * 6, + * 0 + * ] + * ], + * [ + * 6, + * [ + * 5, + * 7, + * 1 + * ] + * ], + * [ + * 7, + * [ + * 8, + * 6, + * 2 + * ] + * ], + * [ + * 8, + * [ + * 9, + * 7, + * 3 + * ] + * ], + * [ + * 9, + * [ + * 8, + * 4, + * 5 + * ] + * ] + * ] + * ], + * [ + * 852054, + * [ + * [ + * 0, + * [ + * 15, + * 10, + * 5 + * ] + * ], + * [ + * 1, + * [ + * 11, + * 6, + * 16 + * ] + * ], + * [ + * 2, + * [ + * 12, + * 7, + * 17 + * ] + * ], + * [ + * 3, + * [ + * 13, + * 8, + * 18 + * ] + * ], + * [ + * 4, + * [ + * 14, + * 9, + * 19 + * ] + * ], + * [ + * 5, + * [ + * 8, + * 7, + * 0 + * ] + * ], + * [ + * 6, + * [ + * 8, + * 9, + * 1 + * ] + * ], + * [ + * 7, + * [ + * 9, + * 5, + * 2 + * ] + * ], + * [ + * 8, + * [ + * 5, + * 6, + * 3 + * ] + * ], + * [ + * 9, + * [ + * 4, + * 6, + * 7 + * ] + * ], + * [ + * 10, + * [ + * 11, + * 0, + * 19 + * ] + * ], + * [ + * 11, + * [ + * 12, + * 10, + * 1 + * ] + * ], + * [ + * 12, + * [ + * 13, + * 11, + * 2 + * ] + * ], + * [ + * 13, + * [ + * 12, + * 14, + * 3 + * ] + * ], + * [ + * 14, + * [ + * 13, + * 15, + * 4 + * ] + * ], + * [ + * 15, + * [ + * 14, + * 0, + * 16 + * ] + * ], + * [ + * 16, + * [ + * 15, + * 1, + * 17 + * ] + * ], + * [ + * 17, + * [ + * 16, + * 2, + * 18 + * ] + * ], + * [ + * 18, + * [ + * 17, + * 3, + * 19 + * ] + * ], + * [ + * 19, + * [ + * 10, + * 4, + * 18 + * ] + * ] + * ] + * ] + * ] + * } + * } + */ + nodeInfo: { + /** @example 20 */ + nodeNumberOfChains: number; + /** @example 0.0 */ + nodeApiVersion: string; + /** + * @example [ + * "0" + * ] + */ + nodeChains: string[]; + /** + * @example mainnet01 + * @enum {string} + */ + nodeVersion: 'test-singleton' | 'development' | 'mainnet01' | 'testnet04'; + /** + * @description Array of all chain graphs indexed by the height of the first block with the repective + * graph. Graphs are encoded as adjacency lists. + */ + nodeGraphHistory: (number | (number | number[])[][])[][]; + }; + /** + * Page + * @description Page of a collection of items + * @example { + * "value": { + * "next": "inclusive:o1S4NNFhKWg8T1HEkmDvsTH9Ut9l3_qHRpp00yRKZIk", + * "items": [ + * "AAAAAAAAAABRoiLHW7EFAB2lwAatTykipYZ3CZNPzLe-f5S-zUt8COtu0H12f_OZAwAFAAAAMpic85rur2MYf3zli8s8bHxTFjriFoMPTr6ZPs8sjxMKAAAAVBKuhU_hQmuvKlx88A5o-FH0rzNo59NsdxmOGNBQ-ycPAAAAMItdqgHZxf7j6l0oE8X-G9-VyMbnQmZrtSniuRe_EJ9CtyxsSb7daPIIYAaXMgSEsQ3dkxY5GjJjLwAAAAAAABqWlmx5B6wo0YWPIShNKmdVrAQWht2P85BS1drGLpkAAAAAADUJ-ARn7blgHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEIPAAAAAAAFAAAA-na5gFuxBQAFL-3CY4YuAJNGp9KhDkbrKkIPWYyq8WvtAaNPoUFWC16louSx8YN5", + * "AAAAAAAAAAA0slHKW7EFAJNGp9KhDkbrKkIPWYyq8WvtAaNPoUFWC16louSx8YN5AwAFAAAAALcxv1ZiwwQ_QX9eOBZMbzIop6n7XtveS1FqOFwyvGMKAAAAC76ElC60qXSJQCHePpzzJxsCYvvrqvmkoHPyZnex-4QPAAAAKv0sz_rTANjoiJwMrdZFCJNFwdH0U_M5ouwMr3BXBfpCtyxsSb7daPIIYAaXMgSEsQ3dkxY5GjJjLwAAAAAAALJlIg1vY3w_9L63bePn1yk_5agvdEbIBBjm3adxc5xWAAAAAGzpBzdiVL9gHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQUIPAAAAAAAFAAAA-na5gFuxBQALiBhXgqaHAb4VWug3oddEVy0X9y_jEkE2Kmi_vyGP5ovr-fDIz_Uf" + * ], + * "limit": 2 + * } + * } + */ + page: { + /** + * @description The number of items in the page. This number can be smaller but + * never be larger than the number of requested items. + */ + limit: number; + /** + * @description A cursor that can be used to query the next page. It should be used + * literally as value for the `next` parameter in a follow-up request. + */ + next: null | string; + /** @description The items in the page. */ + items: Record; + }; + /** + * Mining Update Events + * @description A stream of server-sent events. **This is not an JSON array**. + * Events are separated by empty lines (`\n\n`). Each event + * consists of a single line: + * + * event:New Cut + * + * @example event:New Cut + * + * event:New Cut + * + * event:New Cut + */ + miningUpdateEventStream: { + /** @enum {string} */ + event?: 'New Cut'; + }[]; + /** + * Miner Info + * @example { + * "account": "miner", + * "predicate": "keys-all", + * "public-keys": [ + * "f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27" + * ] + * } + */ + minerInfo: { + /** + * Account Name + * @description Miner account name. Usually this is the same as the public key. + * @example f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27 + */ + account?: string; + /** + * Key Predicate + * @description key predicate. For a single key this is usually `keys-all`. + * @example keys-all + * @enum {unknown} + */ + predicate?: 'keys-all' | 'keys-any'; + 'public-keys'?: string[]; + }; + /** + * Node Configuration + * @description The configuration of a node. Private information regarding certificates + * and local networks are removed. The schema is subject to change and not + * part of the stable API. + * + * @example { + * "value": { + * "allowReadsInLocal": false, + * "rosetta": true, + * "throttling": { + * "local": 1, + * "mining": 2, + * "global": 200, + * "putPeer": 21 + * }, + * "serviceApi": { + * "interface": "invalid", + * "port": 0 + * }, + * "validateHashesOnReplay": false, + * "chainwebVersion": "mainnet01", + * "pactQueueSize": 2000, + * "mining": { + * "coordination": { + * "enabled": false, + * "updateStreamTimeout": 240, + * "limit": 1200, + * "updateStreamLimit": 2000, + * "miners": [] + * }, + * "nodeMining": { + * "miner": { + * "account": "", + * "predicate": "keys-all", + * "public-keys": [] + * }, + * "enabled": false + * } + * }, + * "p2p": { + * "peer": { + * "certificateChainFile": null, + * "key": null, + * "interface": "*", + * "certificateChain": null, + * "hostaddress": { + * "hostname": "34.70.108.163", + * "port": 1789 + * }, + * "keyFile": null + * }, + * "maxPeerCount": 100, + * "private": false, + * "ignoreBootstrapNodes": false, + * "maxSessionCount": 8, + * "bootstrapReachability": 0.5, + * "sessionTimeout": 300, + * "peers": [ + * { + * "address": { + * "hostname": "us-e1.chainweb.com", + * "port": 443 + * }, + * "id": null + * }, + * { + * "address": { + * "hostname": "us-w1.chainweb.com", + * "port": 443 + * }, + * "id": null + * } + * ] + * }, + * "transactionIndex": { + * "enabled": true, + * "configuration": {} + * }, + * "gasLimitOfBlock": 150000, + * "reorgLimit": 480, + * "headerStream": true, + * "mempoolP2p": { + * "enabled": true, + * "configuration": { + * "pollInterval": 30, + * "maxSessionCount": 6, + * "sessionTimeout": 240 + * } + * }, + * "reintroTxs": true, + * "cuts": { + * "pruneChainDatabase": "none", + * "fetchTimeout": 3000000, + * "initialCutHeightLimit": null + * } + * } + * } + */ + nodeConfig: Record; + }; + responses: {}; + parameters: { + /** + * @description Maximum number of records that may be returned. The actual number may be + * lower. + */ + limit: number; + /** + * @description The cursor for the next page. This value can be found as value of the + * `next` property of the previous page. + */ + next: string; + /** @description the id of the chain to which the request is sent */ + chain: number; + /** @description The identifier of the backup being checked */ + backupId: components['schemas']['backupId']; + /** @description Flag, if present back up the Pact databases too. Extra disk space and time required */ + backupPact: string; + /** + * @description Minimum block height of the returned headers + * @example 500000 + */ + minheight: number; + /** + * @description Maximum block height of the returned headers + * @example 500000 + */ + maxheight: number; + /** + * @description Payload hash of a block + * @example { + * "value": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA" + * } + */ + payloadHash: components['schemas']['payloadHash']; + /** + * @description Block hash of a block + * @example { + * "value": [ + * "k0an0qEORusqQg9ZjKrxa-0Bo0-hQVYLXqWi5LHxg3k" + * ] + * } + */ + blockHash: components['schemas']['blockHash']; + }; + requestBodies: { + /** @description Array of request keys */ + requestKeyArray?: { + content: { + 'application/json': components['schemas']['requestKey'][]; + }; + }; + /** @description An array of block payload hashes */ + payloadHashArray?: { + content: { + 'application/json': components['schemas']['payloadHash'][]; + }; + }; + }; + headers: { + /** + * @description The time of the clock of the remote node + * @example 1618597601 + */ + 'x-server-timestamp': components['schemas']['posixTimestamp']; + /** + * @description The version of the remote chainweb node + * @example 2.6 + */ + 'x-chainweb-node-version': string; + /** + * @description Host and port of the client as observed by the remote node + * @example 10.36.1.3:42988 + */ + 'x-peer-addr': components['schemas']['hostAddress']; + }; + pathItems: never; +} + +export type external = Record; + +export type operations = Record; diff --git a/packages/libs/chainweb-node-client/src/openapi/pact.ts b/packages/libs/chainweb-node-client/src/openapi/pact.ts new file mode 100644 index 0000000000..0a5f0c90a4 --- /dev/null +++ b/packages/libs/chainweb-node-client/src/openapi/pact.ts @@ -0,0 +1,629 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +/** Type helpers */ +type Without = { [P in Exclude]?: never }; +type XOR = T | U extends object + ? (Without & U) | (Without & T) + : T | U; +type OneOf = T extends [infer Only] + ? Only + : T extends [infer A, infer B, ...infer Rest] + ? OneOf<[XOR, ...Rest]> + : never; + +export interface paths { + '/local': { + /** + * local + * @description Blocking/sync call to submit a command for non-transactional execution. In a + * blockchain environment this would be a node-local “dirty read”, which can + * either serve as a node-local repl execution, or fully gassed transaction + * simulation and transaction validation. Any database writes or changes to the + * environment are rolled back. + */ + post: { + /** + * local + * @description Blocking/sync call to submit a command for non-transactional execution. In a + * blockchain environment this would be a node-local “dirty read”, which can + * either serve as a node-local repl execution, or fully gassed transaction + * simulation and transaction validation. Any database writes or changes to the + * environment are rolled back. + */ + parameters?: { + /** + * @description Trigger fully-gassed mainnet transaction execution simulation and + * transaction metadata validations. + */ + /** + * @description Require user signature validation when validating transaction + * metadata. + */ + query?: { + preflight?: Record; + signatureValidation?: Record; + }; + }; + requestBody?: { + content: { + 'application/json': components['schemas']['command']; + }; + }; + responses: { + /** @description The command's result. */ + 200: { + content: { + 'application/json': components['schemas']['command-result']; + }; + }; + /** @description The command was invalid. */ + 400: { + content: { + 'text/plain': components['schemas']['validation-failure']; + }; + }; + }; + }; + }; + '/send': { + /** + * send + * @description Asynchronous submission of one or more public (unencrypted) commands + * to the blockchain for execution. + */ + post: { + /** + * send + * @description Asynchronous submission of one or more public (unencrypted) commands + * to the blockchain for execution. + */ + requestBody?: { + content: { + 'application/json': { + cmds: components['schemas']['command'][]; + }; + }; + }; + responses: { + /** @description The commands were successfully submitted. The response contains their request keys. */ + 200: { + content: { + 'application/json': { + /** @description Request keys for use with `poll` or `listen` to retrieve results. */ + requestKeys: components['schemas']['request-key'][]; + }; + }; + }; + /** @description The command failed. */ + 400: { + content: { + 'text/plain': components['schemas']['validation-failure']; + }; + }; + }; + }; + }; + '/poll': { + /** + * poll + * @description Allows polling for one or more command results by request key. + */ + post: { + /** + * poll + * @description Allows polling for one or more command results by request key. + */ + requestBody?: { + content: { + 'application/json': { + requestKeys: components['schemas']['request-key'][]; + }; + }; + }; + responses: { + /** @description The command results for some of the requested request keys. */ + 200: { + content: { + 'application/json': { + [key: string]: + | components['schemas']['command-result'] + | undefined; + }; + }; + }; + }; + }; + }; + '/listen': { + /** + * listen + * @description Blocking request for single command result. + */ + post: { + /** + * listen + * @description Blocking request for single command result. + */ + requestBody?: { + content: { + 'application/json': { + listen: components['schemas']['request-key']; + }; + }; + }; + responses: { + /** @description The request key was found. */ + 200: { + content: { + 'application/json': components['schemas']['command-result']; + }; + }; + }; + }; + }; + '/private': { + /** + * private + * @description Asynchronous submission of a single addressed command which + * will be transmitted with end-to-end encryption only between addressed entity nodes. + * Private payload metadata required. + */ + post: { + /** + * private + * @description Asynchronous submission of a single addressed command which + * will be transmitted with end-to-end encryption only between addressed entity nodes. + * Private payload metadata required. + */ + requestBody?: { + content: { + 'application/json': components['schemas']['command']; + }; + }; + responses: { + /** @description The command was accepted. */ + 200: { + content: { + 'application/json': { + /** @description Request keys for use with `poll` or `listen` to retrieve results. */ + requestKeys?: components['schemas']['request-key'][]; + }; + }; + }; + }; + }; + }; + '/spv': { + /** + * spv + * @description Blocking request to fetch spv proof of a cross chain transaction. Request must be sent to the chain where the transaction is initiated. + */ + post: { + /** + * spv + * @description Blocking request to fetch spv proof of a cross chain transaction. Request must be sent to the chain where the transaction is initiated. + */ + requestBody?: { + content: { + 'application/json': components['schemas']['spv-object']; + }; + }; + responses: { + /** @description The requested spv proof. */ + 200: { + content: { + 'application/json': components['schemas']['spv-proof']; + }; + }; + /** @description The requested spv proof was not findable. */ + 400: { + content: { + 'text/plain': string; + }; + }; + }; + }; + }; +} + +export type webhooks = Record; + +export interface components { + schemas: { + /** + * Pact Command + * @description Represents a single blockchain Pact transaction. + * @example { + * "hash": "H6XjdPHzMai2HLa3_yVkXfkFYMgA0bGfsB0kOsHAMuI", + * "sigs": [ + * { + * "sig": "8d452109cc0439234c093b5e204a7428bc0a54f22704402492e027aaa9375a34c910d8a468a12746d0d29e9353f4a3fbebe920d63bcc7963853995db015d060f" + * } + * ], + * "cmd": "{\"payload\":{\"exec\":{\"data\":null,\"code\":\"(+ 1 2)\"}},\"signers\":[{\"pubKey\":\"368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca\"}],\"meta\":{\"gasLimit\":1000,\"chainId\":\"0\",\"gasPrice\":1.0e-2,\"sender\":\"368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca\"},\"nonce\":\"nonce-value\"}" + * } + */ + command: { + /** @description Stringified JSON `payload` object. Canonic non-malleable signed transaction data. */ + cmd: string; + /** + * @description Unpadded Base64URL of Blake2s-256 hash of the `cmd` field value. Serves as a command + * `requestKey` since each transaction must be unique. + * + * @example H6XjdPHzMai2HLa3_yVkXfkFYMgA0bGfsB0kOsHAMuI + */ + hash: string; + /** @description List of signatures corresponding one-to-one with `signers` array in the payload. */ + sigs: { + /** + * @description Base16-encoded cryptograhic signature of `cmd` field data + * for corresponding signer in payload. + * + * @example 8d452109cc0439234c093b5e204a7428bc0a54f22704402492e027aaa9375a34c910d8a468a12746d0d29e9353f4a3fbebe920d63bcc7963853995db015d060f + */ + sig?: string; + }[]; + }; + /** + * @description Pact Command Payloads are encoded as strings in Pact commands, and contain all + * non-malleable data for a transaction. + * + * @example { + * "payload": { + * "exec": { + * "data": null, + * "code": "(coin.transfer \"Alice\" \"Bob\" 10.0)" + * } + * }, + * "signers": [ + * { + * "pubKey": "368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca", + * "clist": [ + * { + * "name": "coin.TRANSFER", + * "args": [ + * "Alice", + * "Bob", + * 10 + * ] + * } + * ] + * } + * ], + * "meta": { + * "gasLimit": 1000, + * "chainId": "0", + * "gasPrice": 0.01, + * "sender": "368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca" + * }, + * "nonce": "nonce-value" + * } + */ + payload: { + payload: OneOf< + [ + { + /** @description Executable pact code. */ + code?: string; + /** @description Arbitrary JSON to be accessed via `read-msg`, `read-integer` et al in Pact code. */ + data?: Record; + }, + { + /** @description ID of pact running previous step. */ + pactId?: string; + /** @description Step in defpact to execute. */ + step?: number; + /** @description Whether to execute a specified rollback on this step. */ + rollback?: boolean; + /** @description Arbitrary JSON to be accessed via `read-msg`, `read-integer` et al in Pact code. */ + data?: Record; + /** @description Backend-specific data for continuing a cross-chain proof. */ + proof?: string; + }, + ] + >; + meta: OneOf< + [ + { + /** @description Platform-specific chain identifier. For chainweb this is the stringified chain number. */ + chainId: string; + /** @description Indicates gas-paying account. */ + sender: string; + /** @description Limits total amount of gas to be consumed. */ + gasLimit: number; + /** @description Specifies price per gas unit to be charged. */ + gasPrice: number; + /** @description Time in seconds after creation time that transaction can be executed. */ + ttl: number; + /** @description POSIX epoch sending time for transaction. */ + creationTime: number; + }, + { + /** @description Private message envelope address. Required only for private messages, otherwise null. */ + address?: { + /** @description Sender entity name */ + from: string; + /** @description Recipient entity names */ + to: string[]; + }; + }, + ] + >; + /** @description List of signers, corresponding with list of signatures in outer command. */ + signers: { + /** @description Public key image. Pact default is base16 ED25519 encoding. */ + pubKey: string; + /** @description Address, if any. Pact default expects this to match pubKey. */ + address?: string; + /** + * @description Signer scheme. Default is ED25519. + * @enum {string} + */ + scheme?: 'ED25519' | 'ETH'; + /** @description List of capabilities associated with/installed by this signer. */ + clist?: { + /** @description Fully-qualified capability name. */ + name?: string; + args?: components['schemas']['pact-value'][]; + }; + }[]; + /** + * @description Backend-specific identifier of target network. + * @enum {string} + */ + networkId: 'mainnet01' | 'testnet04'; + /** @description Arbitrary user-supplied value. */ + nonce: string; + }; + /** @description Object consisting of data required to fetch proof of a cross chain transaction */ + 'spv-object': { + /** + * @description Request Key of an initiated cross chain transaction at the source chain. + * @example 7af34f24d55d2fcf5de6fccfeeb837698ebff4598303237c64348a47806c8646 + */ + requestKey: string; + /** + * @description Target chain id of the cross chain transaction. + * @example 1 + */ + targetChainId: string; + }; + /** + * Command Result + * @description The result of attempting to execute a single well-formed Pact command. + * @example { + * "gas": 123, + * "result": { + * "status": "success", + * "data": 3 + * }, + * "reqKey": "cQ-guhschk0wTvMBtrqc92M7iYm4S2MYhipQ2vNKxoI", + * "logs": "wsATyGqckuIvlm89hhd2j4t6RMkCrcwJe_oeCYr7Th8", + * "metaData": null, + * "continuation": null, + * "txId": "456", + * "events": [ + * { + * "name": "TRANSFER", + * "params": [ + * "Alice", + * "Bob", + * 10 + * ], + * "module": "coin", + * "moduleHash": "ut_J_ZNkoyaPUEJhiwVeWnkSQn9JT9sQCWKdjjVVrWo" + * } + * ] + * } + */ + 'command-result': { + reqKey: components['schemas']['request-key']; + result: OneOf< + [ + { + /** @enum {string} */ + status?: 'success'; + data?: components['schemas']['pact-value']; + }, + { + /** @enum {string} */ + status?: 'failure'; + error?: components['schemas']['pact-error']; + }, + ] + >; + /** @description Database-internal transaction tracking ID. */ + txId?: number; + /** @description Backend-specific value providing image of database logs. */ + logs: string; + metaData: { + /** @description POSIX time of block */ + blockTime?: number; + /** @description Parent Block hash of containing block. */ + prevBlockHash?: string; + /** @description Block hash of containing block. */ + blockHash?: string; + /** @description Block height of containing block. */ + blockHeight?: number; + /** @description Public metadata. */ + publicMeta?: { + /** @description POSIX time the command was created */ + creationTime?: number; + /** @description Transaction time to live */ + ttl?: number; + /** @description The transaction's gas limit */ + gasLimit?: number; + /** @description Chain identifier */ + chainId?: string; + /** @description The price of each unit of gas in KDA */ + gasPrice?: number; + sender?: string; + }; + }; + events?: components['schemas']['event'][]; + /** @description Describes result of a defpact execution. */ + continuation?: { + /** @description Identifies this defpact execution. On first step generally matches request key. */ + pactId?: string; + /** @description Identifies which step executed in defpact. */ + step?: number; + /** @description Total number of steps in pact. */ + stepCount?: number; + /** @description optional value for private pacts, indicates if step was skipped. */ + executed?: boolean; + /** @description indicates if pact step has rollback. */ + stepHasRollback?: boolean; + /** @description Closure describing executed pact. */ + continuation?: { + /** @description Fully-qualified defpact name. */ + def?: string; + args?: components['schemas']['pact-value'][]; + }; + /** @description Value yielded during pact step, optionally indicating cross-chain execution. */ + yield?: { + /** @description Pact value object containing yielded data. */ + data?: { + [key: string]: components['schemas']['pact-value'] | undefined; + }; + /** @description Source chain ID. */ + source?: string; + provenance?: { + /** @description Chain ID of target chain for next step. */ + targetChainId?: string; + /** @description Hash of module executing defpact. */ + moduleHash?: string; + }; + }; + }; + gas: number; + }; + /** @description Pact value compound type. */ + 'pact-value': + | string + | OneOf< + [ + number, + { + /** + * @description String representation of number to avoid rounding error + * @example 1.23498218000001 + */ + decimal: string; + }, + ] + > + | { + int: number | string; + } + | boolean + | { + [key: string]: components['schemas']['pact-value'] | undefined; + } + | { + /** + * @description Literal time value using the UTC time format. + * @example 1970-01-01T00:00:00Z + */ + time: string; + } + | components['schemas']['pact-value'][] + | { + /** @description Fully-qualified module or interface name. */ + refName?: string; + } + | OneOf< + [ + { + /** @description Set of public key/address values. Native pact public keys are ED25519 in base16 encoding. */ + keys: string[]; + /** + * @description A pact function name. Built-in values are `keys-all` (match all keys in set), + * `keys-any` (match at least one), and `keys-2` (match at least 2). + * Custom functions have a fully-qualified name and + * must accept two integer arguments `count` (number of keys in set) and `matched` + * (number of set keys found in transaction set). + */ + pred: string; + }, + { + /** @description Installed keyset name. */ + keysetref: string; + }, + { + /** @description Fully-qualified guard function name. */ + fun: string; + /** @description Argument values to the guard function. */ + args: components['schemas']['pact-value'][]; + }, + { + moduleName: { + /** @description module bare name */ + name: string; + /** @description module namespace */ + namespace: string; + }; + /** @description Distinguishing/informative name for module guard. */ + name: string; + }, + { + /** @description Defpact execution ID. */ + pactId: string; + /** @description Distinguishing/informative name for pact guard. */ + name: string; + }, + ] + >; + /** @description Pact output event. */ + event: { + /** @description Event defcap name. */ + name?: string; + /** @description Qualified module name of event defcap. */ + module?: { + /** @description module bare name */ + name: string; + /** @description module namespace */ + namespace?: string; + }; + params?: components['schemas']['pact-value'][]; + /** @description Hash of emitting module. */ + moduleHash?: string; + }; + /** @description Verbose object describing failed execution. */ + 'pact-error': { + /** @description Descriptive error text. */ + message: string; + callStack?: string[]; + info?: string; + type?: string; + }; + /** + * Request Key + * @description Unique ID of a pact transaction consisting of its hash. + * @example y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw + */ + 'request-key': string; + /** + * Validation Failure + * @description Failure message of unexecuted command due to an invalid gas payer, meta, or other environments. + */ + 'validation-failure': string; + /** + * SPV Proof + * @description Backend-specific data for continuing a cross-chain proof. + * @example "eyJzdWJqZWN0Ijp7ImlucHV0IjoiQUJSN0ltZGhjeUk2TlRRMExDSnlaWE4xYkhRaU9uc2ljM1JoZEhWeklqb2ljM1ZqWTJWemN5SXNJbVJoZEdFaU9pSlhjbWwwWlNCemRXTmpaV1ZrWldRaWZTd2ljbVZ4UzJWNUlqb2lZa0Y0TjNOd1dqZFdUbUpZWTNocVZFUkNTamt5U21SdlUyVlFjWGx0U25KNWNXOUNhMWcyUkVoYWJ5SXNJbXh2WjNNaU9pSnBRVTF4Y0ZwaVUxSkRaR2hQUzA1YVVYZzFTMHBOTFZOUlNGRlZXRzF4UlZoUlRIRkNUVVpSVFVkSklpd2laWFpsYm5SeklqcGJleUp3WVhKaGJYTWlPbHNpZEdWemRDMXpaVzVrWlhJaUxDSXpaRGxsT1dZeFptSTBZemt6TnpneU5qWmpZV1JrTmpObE4yRTBOMkkzWVRZME5UTmlaVGsyTVdSaU1ETTNNMlkxWXpWbVlUUXdZV05sWlRaaVpHVm1JaXd4WFN3aWJtRnRaU0k2SWxSU1FVNVRSa1ZTSWl3aWJXOWtkV3hsSWpwN0ltNWhiV1Z6Y0dGalpTSTZiblZzYkN3aWJtRnRaU0k2SW1OdmFXNGlmU3dpYlc5a2RXeGxTR0Z6YUNJNkluVjBYMHBmV2s1cmIzbGhVRlZGU21ocGQxWmxWMjVyVTFGdU9VcFVPWE5SUTFkTFpHcHFWbFp5VjI4aWZWMHNJbTFsZEdGRVlYUmhJanB1ZFd4c0xDSmpiMjUwYVc1MVlYUnBiMjRpT201MWJHd3NJblI0U1dRaU9qRXhOams1TkRaOSJ9LCJhbGdvcml0aG0iOiJTSEE1MTJ0XzI1NiIsIm9iamVjdCI6IkFBQUFFQUFBQUFBQUFBQUJBUGhpTkRUdEFHT0l4dWE4OTFYUGU0NVFRS2QtTFdOekNpc0JDeHlmeDliQ0FPUkRnUUR2RFRrWmdOTzZ2M1ZpbU1wZ2ZGd2kyQm1mZ29jRVdwVmxRRW9EQWVoT1JPeFdBckJidXpldnZLTUdQZTB1RlVfUE8yejM3VC0tY0thdDZ1d3pBVm9DbFVrU1lXaXRDODF0TERVd2JYYVFWRTdnZFp1ckN6d0RiZUlBdlpBcUFKVThWZHZkMS1nYmo2UEtIVXdWQm00UWRvNl9YUkpYdHdKTGE4a0N3OWJhQWQtbXRubnlsUkczOC1WcTZzZmlZWm0xd2tKejhZcU5ZT2gwbVZCTktFR1VBTkdQWlB4NGFhMWFDdTJ1Ty1VRkJXLWxLbFdFeFU0a2JjMkszOFZCT21ZeEFDakxpdjMwazdBaGdwVXBCWUIxcEYwWFRqTmU4d3k4aHQta2FveFFKbTZpQVlXSkFYZlpXZERNdkQ3Z1UydUItWFdTVUh3bVpvM3NzV0stRzh1OTIxempBTzllbVBkOFJRVk5jOWZWZWJHN0lMb2lqVDlYMm9Db1p2Q00xQ29yR3laUUFTLVVZd3c4dkJ1bEVVYXlxaHZEQUFreUthbHk1TXk1bzJYVXZpZlZsNkg5QUM5ZXZsczVxMXh2bGhQbE9UWnJZNVB2SDNFbDd3dTBZTTJQYmZzaE1lUGFBUFpZRFJoWncyXzBVM1hIZllQbmJ6QlQ4bkc3a2gtR09kRTBTcFFCNEVOQ0FVWGEzcGVoMnhVd2dCVHd5WFVvc3RDRjNqQ21Scm9ZRGlEUTVGTGhYNkVQQUdlMUF2cFhJazZFM2tpdnUxY1N4aVFYV0hUcW1pdEUwLTVYaVpjNU4zQ3ZBS1dMNmM1RDdQSV84aW0zbG04cWhtZl84UXp3d2ZFcVpXQXZoQ0dWc1VVdCIsImNoYWluIjoxfQ" + */ + 'spv-proof': string; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} + +export type external = Record; + +export type operations = Record; diff --git a/packages/libs/client/src/signing/signWithChainweaver.ts b/packages/libs/client/src/signing/signWithChainweaver.ts index 3d2f240564..051c051cbf 100644 --- a/packages/libs/client/src/signing/signWithChainweaver.ts +++ b/packages/libs/client/src/signing/signWithChainweaver.ts @@ -73,6 +73,12 @@ function isASigner(signer: IQuicksignSigner): signer is { pubKey: string; sig: string; } { + console.log( + 'pubKey' in signer && + 'sig' in signer && + signer.sig !== null && + signer.pubKey.length > 0, + ); return ( 'pubKey' in signer && 'sig' in signer && From 547298443c98feca43ccf69ecf5e0c32a3ec1e8e Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Fri, 24 Feb 2023 20:28:18 +0900 Subject: [PATCH 20/35] update expected value in test --- .../libs/client/src/signing/tests/signWithChainweaver.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts index ae7ec704c4..9d65262f35 100644 --- a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts +++ b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts @@ -172,6 +172,6 @@ describe('signWithChainweaver', () => { await signWithChainweaver(unsignedCommand); - expect(unsignedCommand.sigs).toEqual([{ sig: null }]); + expect(unsignedCommand.sigs).toEqual([undefined]); }); }); From fc7286666b1ad609bd100121fade718e5e2fbb0b Mon Sep 17 00:00:00 2001 From: Kate Hee Kyun Yun <31594593+ggobugi27@users.noreply.github.com> Date: Fri, 24 Feb 2023 20:52:40 +0900 Subject: [PATCH 21/35] Update packages/libs/client/src/signing/tests/signWithChainweaver.test.ts Co-authored-by: Albert G <516972+alber70g@users.noreply.github.com> --- .../libs/client/src/signing/tests/signWithChainweaver.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts index 9d65262f35..059518700a 100644 --- a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts +++ b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts @@ -142,7 +142,7 @@ describe('signWithChainweaver', () => { ]); }); - it('Wallet signs but does not have the signer key and returns sig null', async () => { + it('signs but does not have the signer key and returns sig null', async () => { const mockedResponse: { responses: IQuicksignResponse[] } = { responses: [ { From 69f6e0cf0a1c385cd919c942356fd30fe512674c Mon Sep 17 00:00:00 2001 From: Kate Hee Kyun Yun <31594593+ggobugi27@users.noreply.github.com> Date: Fri, 24 Feb 2023 21:28:33 +0900 Subject: [PATCH 22/35] Update packages/libs/chainweb-node-client/src/tests/local.test.ts Co-authored-by: Albert G <516972+alber70g@users.noreply.github.com> --- packages/libs/chainweb-node-client/src/tests/local.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/libs/chainweb-node-client/src/tests/local.test.ts b/packages/libs/chainweb-node-client/src/tests/local.test.ts index e4cb8a58b0..363865216b 100644 --- a/packages/libs/chainweb-node-client/src/tests/local.test.ts +++ b/packages/libs/chainweb-node-client/src/tests/local.test.ts @@ -32,7 +32,7 @@ test('/local should return result of tx queried', async () => { const signedCommand1: LocalRequestBody = { cmd: commandStr1, hash: cmdWithOneSignature1.hash, - sigs: [{ sig: cmdWithOneSignature1?.sig || null }], + sigs: [{ sig: cmdWithOneSignature1?.sig ?? null }], }; const commandResult1: LocalResponse = { From 6e23872670c60c14594763a0a6310f0b2e2ba03d Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Fri, 24 Feb 2023 21:42:45 +0900 Subject: [PATCH 23/35] remove console.log --- packages/libs/client/src/signing/signWithChainweaver.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/libs/client/src/signing/signWithChainweaver.ts b/packages/libs/client/src/signing/signWithChainweaver.ts index 051c051cbf..3d2f240564 100644 --- a/packages/libs/client/src/signing/signWithChainweaver.ts +++ b/packages/libs/client/src/signing/signWithChainweaver.ts @@ -73,12 +73,6 @@ function isASigner(signer: IQuicksignSigner): signer is { pubKey: string; sig: string; } { - console.log( - 'pubKey' in signer && - 'sig' in signer && - signer.sig !== null && - signer.pubKey.length > 0, - ); return ( 'pubKey' in signer && 'sig' in signer && From 929df9874fdb268440f0f3de5bdf77dfcca0f0d2 Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Fri, 24 Feb 2023 22:03:04 +0900 Subject: [PATCH 24/35] add IQuicksignResponseBody --- packages/libs/client/etc/client.api.md | 6 ++++++ packages/libs/client/src/signing-api/v1/quicksign.ts | 6 ++++++ .../client/src/signing/tests/signWithChainweaver.test.ts | 7 +++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/libs/client/etc/client.api.md b/packages/libs/client/etc/client.api.md index 74b5ba5685..a484b09bf5 100644 --- a/packages/libs/client/etc/client.api.md +++ b/packages/libs/client/etc/client.api.md @@ -183,6 +183,12 @@ export interface IQuicksignResponse { }; } +// @alpha (undocumented) +export interface IQuicksignResponseBody { + // (undocumented) + responses: IQuicksignResponse[]; +} + // @alpha (undocumented) export interface IQuicksignResponseCommand { // (undocumented) diff --git a/packages/libs/client/src/signing-api/v1/quicksign.ts b/packages/libs/client/src/signing-api/v1/quicksign.ts index e0752b628a..8f3f3be38d 100644 --- a/packages/libs/client/src/signing-api/v1/quicksign.ts +++ b/packages/libs/client/src/signing-api/v1/quicksign.ts @@ -27,6 +27,12 @@ export interface IUnsignedQuicksignTransaction { // eslint-disable-next-line @rushstack/no-new-null export type IQuicksignSig = string | null; +/** + * @alpha + */ +export interface IQuicksignResponseBody { + responses: IQuicksignResponse[]; +} /** * @alpha */ diff --git a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts index 059518700a..380b4a521a 100644 --- a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts +++ b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts @@ -6,7 +6,10 @@ jest.mock('cross-fetch', () => { }); import { IPactCommand } from '../../interfaces/IPactCommand'; import { ICommandBuilder, Pact } from '../../pact'; -import { IQuicksignResponse } from '../../signing-api/v1/quicksign'; +import { + IQuicksignResponse, + IQuicksignResponseBody, +} from '../../signing-api/v1/quicksign'; import { signWithChainweaver } from '../signWithChainweaver'; import fetch from 'cross-fetch'; @@ -17,7 +20,7 @@ describe('signWithChainweaver', () => { it('makes a call on 127.0.0.1:9467/v1/quicksign with transaction', async () => { (fetch as jest.Mock).mockResolvedValue({ status: 200, - text: () => JSON.stringify({ responses: [] }), + text: () => JSON.stringify({ responses: [] } as IQuicksignResponseBody), json: () => {}, }); From 996202030bfe810e013289e2880fc481baee3ff1 Mon Sep 17 00:00:00 2001 From: Kate Hee Kyun Yun <31594593+ggobugi27@users.noreply.github.com> Date: Fri, 24 Feb 2023 22:05:43 +0900 Subject: [PATCH 25/35] Update packages/libs/chainweb-node-client/src/tests/send.test.ts Co-authored-by: Albert G <516972+alber70g@users.noreply.github.com> --- packages/libs/chainweb-node-client/src/tests/send.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/libs/chainweb-node-client/src/tests/send.test.ts b/packages/libs/chainweb-node-client/src/tests/send.test.ts index 6835bf7621..e78cec3c7b 100644 --- a/packages/libs/chainweb-node-client/src/tests/send.test.ts +++ b/packages/libs/chainweb-node-client/src/tests/send.test.ts @@ -27,7 +27,7 @@ test('/send should return request keys of txs submitted', async () => { const signedCommand1: ICommand = { cmd: commandStr, hash: cmdWithOneSignature1.hash, - sigs: [{ sig: cmdWithOneSignature1?.sig || null }], + sigs: [{ sig: cmdWithOneSignature1?.sig ?? null }], }; const expectedRequestKey1 = signedCommand1.hash; From 4489e46a02c1cbacf810d14e6a5bf23ee018e212 Mon Sep 17 00:00:00 2001 From: Kate Hee Kyun Yun <31594593+ggobugi27@users.noreply.github.com> Date: Fri, 24 Feb 2023 22:36:24 +0900 Subject: [PATCH 26/35] revert to master --- .../generated-tx-templates/index.ts | 176 +++++++++--------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts index 170fe27b62..e6239260b1 100644 --- a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts +++ b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts @@ -2,114 +2,114 @@ import { buildUnsignedTransaction, ICommandBuilder } from '@kadena/client'; export default { - 'safe-transfer': (args: { - fromAcct: string; - toAcct: string; - amount: string; - chain: string; - network: string; - fromKey: string; + "safe-transfer": (args: { + "fromAcct": string, + "toAcct": string, + "amount": string, + "chain": string, + "network": string, + "fromKey": string, }): ICommandBuilder<{}> => { const parts = [ - 'code: |-\n (coin.transfer "', - '" "', - '" ', - ')\ndata:\npublicMeta:\n chainId: "', - '"\n sender: ', - '\n gasLimit: 2500\n gasPrice: 1.0e-8\n ttl: 600\nnetworkId: ', - '\nsigners:\n - pubKey: ', - '\n caps:\n - name: "coin.TRANSFER"\n args: [', - ', ', - ', ', - ']\n - name: "coin.GAS"\n args: []\ntype: exec\n', + "code: |-\n (coin.transfer \"", + "\" \"", + "\" ", + ")\ndata:\npublicMeta:\n chainId: \"", + "\"\n sender: ", + "\n gasLimit: 2500\n gasPrice: 1.0e-8\n ttl: 600\nnetworkId: ", + "\nsigners:\n - pubKey: ", + "\n caps:\n - name: \"coin.TRANSFER\"\n args: [", + ", ", + ", ", + "]\n - name: \"coin.GAS\"\n args: []\ntype: exec\n" ]; const holes = [ - 'fromAcct', - 'toAcct', - 'amount', - 'chain', - 'fromAcct', - 'network', - 'fromKey', - 'fromAcct', - 'toAcct', - 'amount', + "fromAcct", + "toAcct", + "amount", + "chain", + "fromAcct", + "network", + "fromKey", + "fromAcct", + "toAcct", + "amount" ]; return buildUnsignedTransaction(parts, holes, args); }, - - 'transfer.json': (args: { - fromAcct: string; - toAcct: string; - amount: string; - chain: string; - network: string; - fromKey: string; + + "transfer.json": (args: { + "fromAcct": string, + "toAcct": string, + "amount": string, + "chain": string, + "network": string, + "fromKey": string, }): ICommandBuilder<{}> => { const parts = [ - '{\n "code": "(coin.transfer \\"', - '\\" \\"', - '\\" ', - ')",\n "data": null,\n "publicMeta": {\n "chainId": "', - '",\n "sender": ', - ',\n "gasLimit": 2500,\n "gasPrice": 1e-8,\n "ttl": 600\n },\n "networkId": "', - '",\n "signers": [\n {\n "pubKey": "', - '",\n "caps": [\n {\n "name": "coin.TRANSFER",\n "args": [\n "', - '", "', - '", "', - '"\n ]\n },\n {\n "name": "coin.GAS",\n "args": []\n }\n ]\n }\n ],\n "type": "exec"\n}\n', + "{\n \"code\": \"(coin.transfer \\\"", + "\\\" \\\"", + "\\\" ", + ")\",\n \"data\": null,\n \"publicMeta\": {\n \"chainId\": \"", + "\",\n \"sender\": ", + ",\n \"gasLimit\": 2500,\n \"gasPrice\": 1e-8,\n \"ttl\": 600\n },\n \"networkId\": \"", + "\",\n \"signers\": [\n {\n \"pubKey\": \"", + "\",\n \"caps\": [\n {\n \"name\": \"coin.TRANSFER\",\n \"args\": [\n \"", + "\", \"", + "\", \"", + "\"\n ]\n },\n {\n \"name\": \"coin.GAS\",\n \"args\": []\n }\n ]\n }\n ],\n \"type\": \"exec\"\n}\n" ]; const holes = [ - 'fromAcct', - 'toAcct', - 'amount', - 'chain', - 'fromAcct', - 'network', - 'fromKey', - 'fromAcct', - 'toAcct', - 'amount', + "fromAcct", + "toAcct", + "amount", + "chain", + "fromAcct", + "network", + "fromKey", + "fromAcct", + "toAcct", + "amount" ]; return buildUnsignedTransaction(parts, holes, args); }, - - 'transfer.yaml': (args: { - fromAcct: string; - toAcct: string; - amount: string; - chain: string; - network: string; - fromKey: string; + + "transfer.yaml": (args: { + "fromAcct": string, + "toAcct": string, + "amount": string, + "chain": string, + "network": string, + "fromKey": string, }): ICommandBuilder<{}> => { const parts = [ - 'code: |-\n (coin.transfer "', - '" "', - '" ', - ')\ndata:\npublicMeta:\n chainId: "', - '"\n sender: ', - '\n gasLimit: 2500\n gasPrice: 1.0e-8\n ttl: 600\nnetworkId: ', - '\nsigners:\n - pubKey: ', - '\n caps:\n - name: "coin.TRANSFER"\n args: [', - ', ', - ', ', - ']\n - name: "coin.GAS"\n args: []\ntype: exec\n', + "code: |-\n (coin.transfer \"", + "\" \"", + "\" ", + ")\ndata:\npublicMeta:\n chainId: \"", + "\"\n sender: ", + "\n gasLimit: 2500\n gasPrice: 1.0e-8\n ttl: 600\nnetworkId: ", + "\nsigners:\n - pubKey: ", + "\n caps:\n - name: \"coin.TRANSFER\"\n args: [", + ", ", + ", ", + "]\n - name: \"coin.GAS\"\n args: []\ntype: exec\n" ]; const holes = [ - 'fromAcct', - 'toAcct', - 'amount', - 'chain', - 'fromAcct', - 'network', - 'fromKey', - 'fromAcct', - 'toAcct', - 'amount', + "fromAcct", + "toAcct", + "amount", + "chain", + "fromAcct", + "network", + "fromKey", + "fromAcct", + "toAcct", + "amount" ]; return buildUnsignedTransaction(parts, holes, args); - }, -}; + } +} From bbf964f733dfa0db72d5b8cfe1ed7236497cf7a6 Mon Sep 17 00:00:00 2001 From: Kate Hee Kyun Yun <31594593+ggobugi27@users.noreply.github.com> Date: Fri, 24 Feb 2023 22:37:44 +0900 Subject: [PATCH 27/35] Update index.ts --- .../src/example-templates/generated-tx-templates/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts index e6239260b1..81223c808f 100644 --- a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts +++ b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts @@ -112,4 +112,4 @@ export default { return buildUnsignedTransaction(parts, holes, args); } -} +} From 13f05880a949d5472db47b314bb815e5335b1995 Mon Sep 17 00:00:00 2001 From: Kate Hee Kyun Yun <31594593+ggobugi27@users.noreply.github.com> Date: Fri, 24 Feb 2023 22:38:23 +0900 Subject: [PATCH 28/35] Update index.ts --- .../src/example-templates/generated-tx-templates/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts index 81223c808f..e6239260b1 100644 --- a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts +++ b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts @@ -112,4 +112,4 @@ export default { return buildUnsignedTransaction(parts, holes, args); } -} +} From 6a0a13e86eadbde57c267f822bd4ad59052c41b6 Mon Sep 17 00:00:00 2001 From: Kate Hee Kyun Yun <31594593+ggobugi27@users.noreply.github.com> Date: Fri, 24 Feb 2023 22:36:24 +0900 Subject: [PATCH 29/35] revert to master --- .../src/example-templates/generated-tx-templates/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts index 170fe27b62..303b2404e1 100644 --- a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts +++ b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts @@ -111,5 +111,5 @@ export default { ]; return buildUnsignedTransaction(parts, holes, args); - }, -}; + } +} From 07ab9240cc45dce4e8db320c0d4141566b416fd7 Mon Sep 17 00:00:00 2001 From: Kate Hee Kyun Yun <31594593+ggobugi27@users.noreply.github.com> Date: Fri, 24 Feb 2023 22:37:44 +0900 Subject: [PATCH 30/35] Update index.ts --- .../src/example-templates/generated-tx-templates/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts index 303b2404e1..172613290b 100644 --- a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts +++ b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts @@ -112,4 +112,4 @@ export default { return buildUnsignedTransaction(parts, holes, args); } -} +} From a747ba27929e38e7a66d7b8cd5707c9f3354c811 Mon Sep 17 00:00:00 2001 From: Kate Hee Kyun Yun <31594593+ggobugi27@users.noreply.github.com> Date: Fri, 24 Feb 2023 22:38:23 +0900 Subject: [PATCH 31/35] Update index.ts --- .../src/example-templates/generated-tx-templates/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts index 172613290b..170fe27b62 100644 --- a/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts +++ b/packages/libs/pactjs-test-project/src/example-templates/generated-tx-templates/index.ts @@ -111,5 +111,5 @@ export default { ]; return buildUnsignedTransaction(parts, holes, args); - } -} + }, +}; From 4bf5e954fc5903b6d79120aa367c982064ae9c67 Mon Sep 17 00:00:00 2001 From: Albert G <516972+alber70g@users.noreply.github.com> Date: Fri, 24 Feb 2023 15:16:19 +0100 Subject: [PATCH 32/35] chore: remove generated from openapi spec --- common/config/rush/pnpm-lock.yaml | 31 - common/config/rush/repo-state.json | 2 +- .../libs/chainweb-node-client/package.json | 9 +- .../src/openapi/chainweb.ts | 2087 ----------------- .../chainweb-node-client/src/openapi/pact.ts | 629 ----- 5 files changed, 4 insertions(+), 2754 deletions(-) delete mode 100644 packages/libs/chainweb-node-client/src/openapi/chainweb.ts delete mode 100644 packages/libs/chainweb-node-client/src/openapi/pact.ts diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 8a07c023cf..ab03720144 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -307,8 +307,6 @@ importers: cross-fetch: ~3.1.5 eslint: ^8.15.0 node-fetch: ~2.6.2 - openapi-typescript: ~6.1.0 - openapi-typescript-fetch: ~1.1.3 dependencies: '@kadena/cryptography-utils': link:../cryptography-utils '@kadena/pactjs': link:../pactjs @@ -325,8 +323,6 @@ importers: '@types/heft-jest': 1.0.3 '@types/node': 16.18.7 eslint: 8.29.0 - openapi-typescript: 6.1.0 - openapi-typescript-fetch: 1.1.3 ../../packages/libs/chainwebjs: specifiers: @@ -4985,11 +4981,6 @@ packages: string-width: 4.2.3 dev: true - /ansi-colors/4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - dev: true - /ansi-escapes/4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -9770,23 +9761,6 @@ packages: is-wsl: 2.2.0 dev: false - /openapi-typescript-fetch/1.1.3: - resolution: {integrity: sha512-smLZPck4OkKMNExcw8jMgrMOGgVGx2N/s6DbKL2ftNl77g5HfoGpZGFy79RBzU/EkaO0OZpwBnslfdBfh7ZcWg==} - engines: {node: '>= 12.0.0', npm: '>= 7.0.0'} - dev: true - - /openapi-typescript/6.1.0: - resolution: {integrity: sha512-4G0hQu9zXHESZe4fZouucmA+6J5oKSBNYzG0gPbV9V4aKBNIwfUY86ur/cxyTMzuN9vQuAiMe//q4ZMXgMvGtQ==} - hasBin: true - dependencies: - ansi-colors: 4.1.3 - fast-glob: 3.2.12 - js-yaml: 4.1.0 - supports-color: 9.3.1 - undici: 5.14.0 - yargs-parser: 21.1.1 - dev: true - /optimism/0.16.2: resolution: {integrity: sha512-zWNbgWj+3vLEjZNIh/okkY2EUfX+vB9TJopzIZwT1xxaMqC5hRLLraePod4c5n4He08xuXNH+zhKFFCu390wiQ==} dependencies: @@ -11338,11 +11312,6 @@ packages: dependencies: has-flag: 4.0.0 - /supports-color/9.3.1: - resolution: {integrity: sha512-knBY82pjmnIzK3NifMo3RxEIRD9E0kIzV4BKcyTZ9+9kWgLMxd4PrsTSMoFQUabgRBbF8KOLRDCyKgNV+iK44Q==} - engines: {node: '>=12'} - dev: true - /supports-hyperlinks/2.3.0: resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} engines: {node: '>=8'} diff --git a/common/config/rush/repo-state.json b/common/config/rush/repo-state.json index 765ca0a9a7..ee9e5a076d 100644 --- a/common/config/rush/repo-state.json +++ b/common/config/rush/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "f6ff508d606bbd16187ce03e9a87eb8d0ce6e71a", + "pnpmShrinkwrapHash": "ba8b267af803a5ec6df145e148a5a9f8ae2b3ba7", "preferredVersionsHash": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f" } diff --git a/packages/libs/chainweb-node-client/package.json b/packages/libs/chainweb-node-client/package.json index c96de834c4..ff10566ac3 100644 --- a/packages/libs/chainweb-node-client/package.json +++ b/packages/libs/chainweb-node-client/package.json @@ -28,9 +28,8 @@ "_phase:build": "heft build --clean", "_phase:test": "heft test --no-build", "build": "heft build --clean", - "generate:chainweb:client": "openapi-typescript ./openapi/chainweb.json --output ./src/openapi/chainweb.ts", - "generate:pact:client": "openapi-typescript ./openapi/pact.json --output ./src/openapi/pact.ts", - "postinstall": "npm run generate:pact:client && npm run generate:chainweb:client", + "generate:openapi-types": "echo 'openapi specs needs fixes' # openapi-typescript \"./openapi/*.json\" --output ./src/openapi", + "postinstall": "npm run generate:openapi-types", "lint": "npx eslint ./src --ext .js,.ts --fix", "test": "rushx build && heft test --no-build" }, @@ -59,8 +58,6 @@ "@rushstack/heft": "~0.46.1", "@types/heft-jest": "~1.0.3", "@types/node": "^16.0.0", - "eslint": "^8.15.0", - "openapi-typescript": "~6.1.0", - "openapi-typescript-fetch": "~1.1.3" + "eslint": "^8.15.0" } } diff --git a/packages/libs/chainweb-node-client/src/openapi/chainweb.ts b/packages/libs/chainweb-node-client/src/openapi/chainweb.ts deleted file mode 100644 index 3e33b0ab65..0000000000 --- a/packages/libs/chainweb-node-client/src/openapi/chainweb.ts +++ /dev/null @@ -1,2087 +0,0 @@ -/** - * This file was auto-generated by openapi-typescript. - * Do not make direct changes to the file. - */ - -export interface paths { - '/cut': { - /** Query the current cut */ - get: { - /** Query the current cut */ - parameters?: { - /** @description Maximum cut height of the returned cut */ - query?: { - maxheight?: number; - }; - }; - responses: { - /** @description The current cut */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': components['schemas']['cut']; - }; - }; - }; - }; - /** - * Publish a cut - * @description Publish a cut to a Chainweb node. - * - * The cut must contain an origin property that is not `null`. The receiving node - * will first try to obtain all missing dependencies from the node that is - * indicated in by the origin property before searching for the dependencies in the - * P2P network. - */ - put: { - /** - * Publish a cut - * @description Publish a cut to a Chainweb node. - * - * The cut must contain an origin property that is not `null`. The receiving node - * will first try to obtain all missing dependencies from the node that is - * indicated in by the origin property before searching for the dependencies in the - * P2P network. - */ - /** @description A cut with an origin property that is not `null`. */ - requestBody: { - content: { - /** - * @example { - * "value": { - * "origin": null, - * "height": 30798466, - * "weight": "b0wYplmNiTBXCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - * "hashes": { - * "0": { - * "height": 1539923, - * "hash": "qEaSmWt_tDcJC9AGbgWY9x12LW5VED7hGgfyz9x_S3w" - * }, - * "1": { - * "height": 1539923, - * "hash": "TJuC6nfhamfD517gspAZmqD9umR71nAgttDOi1JbBHw" - * }, - * "2": { - * "height": 1539924, - * "hash": "4ineCWfnO1rneWuBMLPzqTl2HF_sZpypT_3TEzf3VLc" - * }, - * "3": { - * "height": 1539924, - * "hash": "ZEOMXB2ByqzL2HfYVKIZKAnoe4wIeJ2SaltnXDir59k" - * }, - * "4": { - * "height": 1539923, - * "hash": "0g0rOoSznVW2BJDBmK0Lbxz22F-sxTZUNIrUs_Q8Ye4" - * }, - * "5": { - * "height": 1539923, - * "hash": "5y_TL-clnF_wELMBKyJk0Sz8RVShw_bGQETJdrMkADA" - * }, - * "6": { - * "height": 1539923, - * "hash": "YkQKv6P4_C4jRM3RqKK9FWPxIneeLzlkKQS9ATAQYRk" - * }, - * "7": { - * "height": 1539923, - * "hash": "j_hJ9iiH_ATyeQeeRN3auGXjbBWiFgnTU0dYPIz8cKM" - * }, - * "8": { - * "height": 1539924, - * "hash": "s7c3B55VbDsS6EJ-nc9S5k2kNbPOBGI8xxF3vUg4d4Q" - * }, - * "9": { - * "height": 1539922, - * "hash": "bowQf63xSY9owHKhK1yGee2Q0Fn8yL_oCLaEUn-CGoA" - * }, - * "10": { - * "height": 1539924, - * "hash": "uP-pHW4QKrV9fN1mlDGwKuaiIDlJW7xYSj1nW53EHM4" - * }, - * "11": { - * "height": 1539924, - * "hash": "TIhegjZ0GEC73T4m0BVuFtfLNGuS56IUWEuf93AJ5UU" - * }, - * "12": { - * "height": 1539923, - * "hash": "-j1qcAS9Fs-WQmc3WEhzZ96VojxnlIA2TFpfyIv31Zs" - * }, - * "13": { - * "height": 1539923, - * "hash": "S-4TqMgWGlK1k33XRlU9w0Lfwr0RvkO5Jn78Au1OglM" - * }, - * "14": { - * "height": 1539923, - * "hash": "xSuULf--S4TrgYNz82deaGhnPLWrg3pXkynGeUPUGwA" - * }, - * "15": { - * "height": 1539923, - * "hash": "jsc9rugvcHXDiBAuoO9_j8R_b_jchtJJ8b5596i8wVg" - * }, - * "16": { - * "height": 1539923, - * "hash": "qs1aEY8kSxfUBb_JRVswv5dYINRXBjGJteC-6RC1hjc" - * }, - * "17": { - * "height": 1539924, - * "hash": "xzVBXaQxzlUfUrakDgppUubQBRXGh-Uy0HBdMNwCq_Y" - * }, - * "18": { - * "height": 1539924, - * "hash": "4VOHPAqwioySYRycdl5MxfscQHwtlwwCAt7AySYQT98" - * }, - * "19": { - * "height": 1539923, - * "hash": "1PrRg20XyQ_2cfgGOgNK9K-cqIJ1vO8-A-RJlfN5m00" - * } - * }, - * "id": "BBz7KeurYTeQ0hMGbwUbQC84cRbVcacoDQTye-3qkXI", - * "instance": "mainnet01" - * } - * } - */ - 'application/json': components['schemas']['cut'] & - Record; - }; - }; - responses: { - /** @description The cut was added to the cut processing pipeline of the remote node */ - 204: never; - /** @description The requester is not a peer of this node, and thus not allowed to send it cuts */ - 401: never; - }; - }; - }; - '/cut/peer': { - /** Get Cut-Network Peer Info */ - get: { - /** Get Cut-Network Peer Info */ - responses: { - /** @description Peers from the peer database of the remote node */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - /** @description Array of peers */ - items?: Record; - } & components['schemas']['page']; - }; - }; - }; - }; - /** Put Cut-Network Peer Info */ - put: { - /** Put Cut-Network Peer Info */ - /** - * @description The peer that is added to the peer database of the cut P2P network of - * the remote host. - */ - requestBody?: { - content: { - 'application/json': components['schemas']['peer'] & { - id?: Record | null; - }; - }; - }; - responses: { - /** @description The peer got added to the peer database of the remote node. */ - 204: never; - /** - * @description The request is invalid. It is either malformed or the provided peer - * is not reachable. - * - * Before the remote node adds a peer to its peer database it checks - * whether the peer can be reached via the provided address. If this - * check fails an error is returned. - */ - 400: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'text/plain': unknown; - }; - }; - }; - }; - }; - '/chain/{chain}/hash': { - /** Get Block Hashes */ - get: { - /** Get Block Hashes */ - responses: { - /** - * @description A page of a collection of block hashes in **ascending** order - * that satisfies query parameters. Any block hash from the chain - * database is returned. **This includes hashes of orphaned blocks.** - */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - /** @description Array of block hashes */ - items?: Record; - } & components['schemas']['page']; - }; - }; - /** @description A parameter indicated a nonexistent block height. */ - 404: { - content: { - 'application/json': { - reason?: string; - key?: components['schemas']['blockHash']; - }; - }; - }; - }; - }; - }; - '/chain/{chain}/hash/branch': { - /** - * Get Block Hash Branches - * @description A page of block hashes from branches of the block chain in - * **descending** order. - * - * Only blocks are returned that are ancestors of the some block in the - * set of upper bounds and are not ancestors of any block in the set of - * lower bounds. - */ - post: { - /** - * Get Block Hash Branches - * @description A page of block hashes from branches of the block chain in - * **descending** order. - * - * Only blocks are returned that are ancestors of the some block in the - * set of upper bounds and are not ancestors of any block in the set of - * lower bounds. - */ - /** @description Upper and lower bounds of the queried branches */ - requestBody?: { - content: { - 'application/json': { - /** - * @description No block hashes are returned that are predecessors of any - * block with a hash from this array. - */ - lower?: components['schemas']['blockHash'][]; - /** - * @description Returned block hashes are predecessors of a block with an - * hash from this array. This includes blocks with hashes from - * this array. - */ - upper?: components['schemas']['blockHash'][]; - }; - }; - }; - responses: { - /** @description The requested block hashes */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - /** @description Array of block hashes */ - items?: Record; - } & components['schemas']['page']; - }; - }; - /** @description The requested block hashes could not be found */ - 404: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - reason?: string; - key?: components['schemas']['blockHash']; - }; - }; - }; - }; - }; - }; - '/chain/{chain}/header': { - /** - * Get Block Headers - * @description A page of a collection of block headers in **ascending** order - * that satisfies query parameters. Any block header from the chain - * database is returned. **This includes headers of orphaned blocks.** - */ - get: { - /** - * Get Block Headers - * @description A page of a collection of block headers in **ascending** order - * that satisfies query parameters. Any block header from the chain - * database is returned. **This includes headers of orphaned blocks.** - */ - responses: { - /** @description The requested block headers */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - /** @description Array of base64 encoded block headers */ - items?: components['schemas']['base64Header'][]; - } & components['schemas']['page']; - 'application/json;blockheader-encoding=object': { - /** @description Array of JSON encoded block headers */ - items?: Record; - } & components['schemas']['page']; - }; - }; - /** @description The `next` or `maxheight` parameter indicated a nonexistent block height. */ - 404: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - reason?: string; - key?: components['schemas']['blockHash']; - }; - }; - }; - }; - }; - }; - '/chain/{chain}/header/{blockHash}': { - /** - * Get Block Header by Hash - * @description Query a block header by its hash - */ - get: { - /** - * Get Block Header by Hash - * @description Query a block header by its hash - */ - responses: { - /** @description The block header with that hash was found */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': components['schemas']['base64Header']; - 'application/json;blockheader-encoding=object': components['schemas']['blockHeader']; - 'application/octet-stream': components['schemas']['binaryHeader']; - }; - }; - /** @description A block header with that block hash was not found. */ - 404: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - reason?: string; - key?: components['schemas']['blockHash']; - }; - }; - }; - /** @description The value of the `Accept` header is not supported. */ - 406: never; - }; - }; - }; - '/chain/{chain}/header/branch': { - /** - * Get Block Header Branches - * @description A page of block headers from branches of the block chain in - * **descending** order. - * - * Only blocks are returned that are ancestors of the some block in the - * set of upper bounds and are not ancestors of any block in the set of - * lower bounds. - */ - post: { - /** - * Get Block Header Branches - * @description A page of block headers from branches of the block chain in - * **descending** order. - * - * Only blocks are returned that are ancestors of the some block in the - * set of upper bounds and are not ancestors of any block in the set of - * lower bounds. - */ - /** @description Upper and lower bounds of the queried branches */ - requestBody?: { - content: { - 'application/json': { - /** - * @description No blocks are returned that are predecessors of any block with - * an hash from this array. - */ - lower?: components['schemas']['blockHash'][]; - /** - * @description Returned block headers are predecessors of a block with an - * hash from this array. This includes blocks with hashes from - * this array. - */ - upper?: components['schemas']['blockHash'][]; - }; - }; - }; - responses: { - /** @description The block headers were found */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - /** @description Array of base64 encoded block headers */ - items?: Record; - } & components['schemas']['page']; - 'application/json;blockheader-encoding=object': { - /** @description Array of JSON encoded block headers */ - items?: Record; - } & components['schemas']['page']; - }; - }; - /** @description A block header indicated by a required parameter was not found. */ - 404: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - reason?: string; - key?: components['schemas']['blockHash']; - }; - }; - }; - /** @description The value of the `Accept` header is not supported. */ - 406: never; - }; - }; - }; - '/chain/{chain}/payload/{payloadHash}': { - /** Get Block Payload */ - get: { - /** Get Block Payload */ - responses: { - /** @description The payload data of for the given block payload hash */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': components['schemas']['payload']; - }; - }; - /** @description The block payload with that hash was not found */ - 404: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - /** @description Failure message */ - reason?: string; - key?: components['schemas']['payloadHash']; - }; - }; - }; - }; - }; - }; - '/chain/{chain}/payload/batch': { - /** Get Batch of Block Payload */ - post: { - /** Get Batch of Block Payload */ - requestBody: components['requestBodies']['payloadHashArray']; - responses: { - /** - * @description Array of the some or all of the requested block payloads. The - * payloads may be returned in any order. - */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': components['schemas']['payload'][]; - }; - }; - }; - }; - }; - '/chain/{chain}/payload/{payloadHash}/outputs': { - /** Get Block Payload With Outputs */ - get: { - /** Get Block Payload With Outputs */ - responses: { - /** @description The payload with outputs for the given block payload hash */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': components['schemas']['payloadWithOutputs']; - }; - }; - /** @description A block payload with that hash was not found */ - 404: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - /** @description Failure message */ - reason?: string; - key?: components['schemas']['payloadHash']; - }; - }; - }; - }; - }; - }; - '/chain/{chain}/payload/outputs/batch': { - /** Get Batch of Block Payload With Outputs */ - post: { - /** Get Batch of Block Payload With Outputs */ - requestBody: components['requestBodies']['payloadHashArray']; - responses: { - /** - * @description Array of the some or all of the requested block payloads with - * outputs. Result items maybe returned in any order. - */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': components['schemas']['payloadWithOutputs'][]; - }; - }; - }; - }; - }; - '/chain/{chain}/mempool/getPending': { - /** Get Pending Transactions from the Mempool */ - post: { - /** Get Pending Transactions from the Mempool */ - parameters?: { - /** @description Server nonce value */ - /** @description Mempool tx id value */ - query?: { - nonce?: number; - since?: number; - }; - }; - responses: { - /** @description recent state of pending transactions in the mempool */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - hashes?: string[]; - /** @description two-element array: `[nonce (integer), since (int64)]` */ - highwaterMark?: number[]; - }; - }; - }; - }; - }; - }; - '/chain/{chain}/mempool/member': { - /** Check for Pending Transactions in the Mempool */ - post: { - /** Check for Pending Transactions in the Mempool */ - requestBody: components['requestBodies']['requestKeyArray']; - responses: { - /** - * @description Array of boolean values that indicate whether the respective - * transaction is in the mempool. - * - * The array has the same size as the request body. - */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': boolean[]; - }; - }; - }; - }; - }; - '/chain/{chain}/mempool/lookup': { - /** Lookup Pending Transactions in the Mempool */ - post: { - /** Lookup Pending Transactions in the Mempool */ - requestBody: components['requestBodies']['requestKeyArray']; - responses: { - /** @description Array of lookup results for the respective transactions */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - /** @enum {string} */ - tag?: 'Missing' | 'Pending'; - contents?: components['schemas']['signedTxText']; - }[]; - }; - }; - }; - }; - }; - '/chain/{chain}/mempool/insert': { - /** Insert Transactions into the Mempool */ - put: { - /** Insert Transactions into the Mempool */ - /** @description Array of strings of JSON encoded signed transactions */ - requestBody?: { - content: { - 'application/json': components['schemas']['signedTxText'][]; - }; - }; - responses: { - /** @description Transactions were inserted */ - 200: never; - }; - }; - }; - '/chain/{chain}/mempool/peer': { - /** Get Chain Mempool-Network Peer Info */ - get: { - /** Get Chain Mempool-Network Peer Info */ - responses: { - /** @description Peer information */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': { - /** @description Array of peers */ - items?: Record; - } & components['schemas']['page']; - }; - }; - }; - }; - /** Put Chain Mempool-Network Peer Info */ - put: { - /** Put Chain Mempool-Network Peer Info */ - /** - * @description The peer that is added to the peer database of the mempoo P2P network of - * the chain `{chain}` of remote host. - */ - requestBody?: { - content: { - 'application/json': components['schemas']['peer'] & { - id?: Record | null; - }; - }; - }; - responses: { - /** @description The peer got added to the peer database of the remote node. */ - 204: never; - /** - * @description Bad Request. - * The request is invalid. It is either malformed or the provided peer is not reachable. - * - * Before the remote node addes a peer to its peer database it checks whether the peer can be reached - * via the provided address. If this check fails an error is returned. - */ - 400: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'text/plain': unknown; - }; - }; - }; - }; - }; - '/mining/work': { - /** - * Get Mining Work - * @description A new BlockHeader to mine on - */ - get: { - /** - * Get Mining Work - * @description A new BlockHeader to mine on - */ - /** @description Miner Info */ - requestBody?: { - content: { - /** - * @example { - * "account": "miner", - * "predicate": "keys-all", - * "public-keys": [ - * "f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27" - * ] - * } - */ - 'application/json': components['schemas']['minerInfo']; - }; - }; - responses: { - /** @description A mining work item */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/octet-stream': { - /** - * 4 Chain ID Bytes - * Format: binary - * @description The chain selection made by the Node. This is - * informational. Generally, miner should not care about the - * chain. - */ - chainBytes?: string; - /** - * 32 PoW Target Bytes - * Format: binary - * @description The PoW target for the current block. The PoW hash of a - * valid block must not be larger than this value. - * - * For arithmetic comparisons the hash-target and the PoW - * hash are interpreted as unsigned 256 bit integral number - * in little endian encoding. - */ - targetBytes?: string; - /** - * 286 Work Header Bytes - * Format: binary - * @description PoW Work Header Bytes. The last 8 bytes are the nonce. The - * creation time is encoded in bytes 44-52. Miners must not - * change or make any assumption about the other bytes. - * - * The creation time is encoded as little endian twoth - * complement integral number that counts SI microseconds - * since POSIX epoch (leap seconds are ignored). It always - * positive (highest bit is 0). Miners are free but not - * required to update the creation time. The value must be - * strictly larger than the creation time of the parent block - * and must not be in the future. - */ - headerBytes?: string; - }; - }; - }; - }; - }; - }; - '/chainweb/0.0/mainnet01/mining/solved': { - /** - * Solved Mining Work - * @description Submit a solution for a new block - */ - post: { - /** - * Solved Mining Work - * @description Submit a solution for a new block - */ - /** @description The solved PoW work header bytes */ - requestBody?: { - content: { - 'application/octet-stream': string; - }; - }; - responses: { - /** @description Solved mining work is valid */ - 204: never; - }; - }; - }; - '/mining/updates': { - /** - * Notification of Updated Work - * @description An server-sent event sources that notifies miners when new mining - * work becomes available. - * - * The stream is terminated by the server in regular intervals and - * it is up to the client to request a new stream. - */ - get: { - /** - * Notification of Updated Work - * @description An server-sent event sources that notifies miners when new mining - * work becomes available. - * - * The stream is terminated by the server in regular intervals and - * it is up to the client to request a new stream. - */ - /** @description The first 4 bytes received from a call to `/mining/work`. This tells the Node to only inform the Miner of a new Cut when the specific chain in question has updated. */ - requestBody?: { - content: { - 'application/octet-stream': string; - }; - }; - responses: { - /** - * @description Each events consists of a single line: `event:New Cut`. - * Events are separated by empty lines. - */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'text/event-stream': components['schemas']['miningUpdateEventStream']; - }; - }; - }; - }; - }; - '/config': { - /** - * Configuration of Chainweb Node - * @description Returns the configuration of chainweb-node as a JSON structure. - * Sensitive information is removed from the result. The JSON schema depends - * on the chainweb node version and is not part of the stable chainweb-node - * API. - */ - get: { - /** - * Configuration of Chainweb Node - * @description Returns the configuration of chainweb-node as a JSON structure. - * Sensitive information is removed from the result. The JSON schema depends - * on the chainweb node version and is not part of the stable chainweb-node - * API. - */ - responses: { - /** @description Configuration of the chainweb node */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': unknown; - }; - }; - }; - }; - }; - '/make-backup': { - /** - * Start a backup job - * @description Backup jobs are identified by the Unix timestamp when they're begun. - * - * If a backup job is already in progress, this endpoint will return its - * identifier instead of starting a new one. - * - * The RocksDB portion of the database is always backed up; if backupPact - * is set, the Sqlite (Pact) portion is backed up as well, taking much - * longer. - * - * There is no automatic backup retention policy - users need to delete old - * backups. - * - * This API is enabled by configuring the node thus: - * ```yaml - * backup: - * api: - * enabled: true - * directory: {some file path to put backups in} - * ``` - * The backup directory ideally will be located in the same partition as the - * RocksDB portion of the node database. - * - * RocksDB backups to the same partition as holds the active RocksDB - * database will have almost zero space overhead immediately, but over time - * as the active database diverges from the backup the space overhead will - * increase. If the backup is to another partition, it will take longer - * and take as much disk space as the active RocksDB database. - * - * Pact database backups always require about as much space as the active - * Pact database does. - */ - post: { - /** - * Start a backup job - * @description Backup jobs are identified by the Unix timestamp when they're begun. - * - * If a backup job is already in progress, this endpoint will return its - * identifier instead of starting a new one. - * - * The RocksDB portion of the database is always backed up; if backupPact - * is set, the Sqlite (Pact) portion is backed up as well, taking much - * longer. - * - * There is no automatic backup retention policy - users need to delete old - * backups. - * - * This API is enabled by configuring the node thus: - * ```yaml - * backup: - * api: - * enabled: true - * directory: {some file path to put backups in} - * ``` - * The backup directory ideally will be located in the same partition as the - * RocksDB portion of the node database. - * - * RocksDB backups to the same partition as holds the active RocksDB - * database will have almost zero space overhead immediately, but over time - * as the active database diverges from the backup the space overhead will - * increase. If the backup is to another partition, it will take longer - * and take as much disk space as the active RocksDB database. - * - * Pact database backups always require about as much space as the active - * Pact database does. - */ - responses: { - /** @description A backup job has been created */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'text/plain': components['schemas']['backupId']; - }; - }; - }; - }; - }; - '/check-backup/{backupId}': { - /** Check the status of a backup job */ - get: { - /** Check the status of a backup job */ - responses: { - /** @description A backup job with that identifier exists, here is its status */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'text/plain': components['schemas']['backupStatus']; - }; - }; - /** @description There is no backup job with that identifier */ - 404: never; - }; - }; - }; - '/health-check': { - /** - * Health Check - * @description Checks whether the chainweb-node is up and running and responding to API - * requests. In order to check the state of consensus the - * [/cut/get](#tag/cut/paths/~1cut/get) endpoint should be used instead. - */ - get: { - /** - * Health Check - * @description Checks whether the chainweb-node is up and running and responding to API - * requests. In order to check the state of consensus the - * [/cut/get](#tag/cut/paths/~1cut/get) endpoint should be used instead. - */ - responses: { - /** @description The node is healthy */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'text/plain': string; - }; - }; - }; - }; - }; - '/info': { - /** - * General Node Info - * @description Provides general information about the node and the chainweb version - */ - get: { - /** - * General Node Info - * @description Provides general information about the node and the chainweb version - */ - responses: { - /** @description General information about the node and the chainweb version */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'application/json': components['schemas']['nodeInfo']; - }; - }; - }; - }; - }; - '/header/updates': { - /** - * Blocks Event Stream - * @description An source of server events that emits a `BlockHeader` event for each new - * block header that is added to the chain database of the remote node. - * - * The stream contains blocks that may later become orphaned. It is - * therefor recommended to buffer events on the client side for the most - * recent block heights until the desired confirmation depth is reached. - * - * The server may terminate this stream from time to time and it is up to - * the client to reinitiate the stream. - */ - get: { - /** - * Blocks Event Stream - * @description An source of server events that emits a `BlockHeader` event for each new - * block header that is added to the chain database of the remote node. - * - * The stream contains blocks that may later become orphaned. It is - * therefor recommended to buffer events on the client side for the most - * recent block heights until the desired confirmation depth is reached. - * - * The server may terminate this stream from time to time and it is up to - * the client to reinitiate the stream. - */ - responses: { - /** - * @description A stream of `BlockHeader` events. **This is not a JSON array**. - * - * Events are separated by empty lines. Each event consists of an - * `event` property and a `data` property which are separated by - * newlines. - */ - 200: { - headers: { - 'x-peer-addr': components['headers']['x-peer-addr']; - 'x-server-timestamp': components['headers']['x-server-timestamp']; - 'x-chainweb-node-version': components['headers']['x-chainweb-node-version']; - }; - content: { - 'text/event-stream': { - /** @enum {string} */ - event?: 'BlockHeader'; - data?: { - /** @description Number of transactions in the block */ - txCount?: number; - /** @description A custom representation of the POW hash for use in the block explorer UI */ - powHash?: string; - header?: components['schemas']['blockHeader']; - /** @description A custom representation of the POW target for use in the block explorer UI */ - target?: string; - }; - }[]; - }; - }; - }; - }; - }; -} - -export type webhooks = Record; - -export interface components { - schemas: { - /** - * POSIX Timestamp - * @description Seconds since POSIX epoch - * @example 1619108524 - */ - posixTimestamp: number; - /** - * POSIX Timestamp in Microseconds - * @description Microseconds since POSIX epoch - * @example 1602382624629329 - */ - posixTimestampMicro: number; - /** - * Chainweb Version - * @description The version of the Chainweb network - * @enum {unknown} - */ - chainwebVersion: - | 'test-singleton' - | 'development' - | 'mainnet01' - | 'testnet04'; - /** - * Chain ID - * @description A Chainweb chain ID. In Kadena Chainweb chains are named by numbers - * starting form 0. Valid values depend on the current graph at the - * respective block height of the chainweb version. - * - * @example 0 - */ - chainId: number; - /** - * Host Address - * @description Host address containing IPv4 and port - * @example 10.36.1.3:42988 - */ - hostAddress: string; - /** - * Signed Transaction Text - * @description Text of a JSON encoded signed Pact transaction - * @example { - * "value": { - * "hash": "y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw", - * "sigs": [ - * { - * "sig": "8ddc06b37c496f2cadc4f7412405a80faf3ab07482ff5553b9b5fcc73d1b4121275ad5948d9b4078e553b71f8b42eaf6b24135bf2fb4d5840c16bcdde0e35e0f" - * } - * ], - * "cmd": "{\"networkId\":\"mainnet01\",\"payload\":{\"exec\":{\"data\":{\"account-keyset\":{\"pred\":\"keys-all\",\"keys\":[\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\"]}},\"code\":\"(coin.transfer-create \\\"60241f51ea34e05c61fbea9d\\\" \\\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\\\" (read-keyset \\\"account-keyset\\\") 5007.0000)\"}},\"signers\":[{\"pubKey\":\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\",\"clist\":[{\"args\":[\"60241f51ea34e05c61fbea9d\",\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\",5007],\"name\":\"coin.TRANSFER\"},{\"args\":[],\"name\":\"coin.GAS\"}]}],\"meta\":{\"creationTime\":1618949714,\"ttl\":300,\"gasLimit\":600,\"chainId\":\"0\",\"gasPrice\":1.0e-7,\"sender\":\"acc28032a1bb725b7ba0a3593ab86f393894fa6659281f3dfdfee0afe48559a2\"},\"nonce\":\"\\\"2021-04-20T20:16:13.645Z\\\"\"}" - * } - * } - */ - signedTxText: string; - /** - * Request Key - * @description Base64Url-encoded, request key of a Pact transaction - * @example y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw - */ - requestKey: string; - /** - * SHA256 Hash - * @description Base64Url (without padding) encoded SHA256 hash - * @example y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw - */ - sha256Hash: string; - /** - * Block Hash - * @description Base64Url (without padding) encoded block hash - * @example QxGCAz5AY1Y41nh1yWtgqhKhZ9pPiPRagFdIKNqBH7 - */ - blockHash: components['schemas']['sha256Hash']; - /** - * Block Payload Hash - * @description Base64Url (without padding) encoded block payload hash - * @example GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA - */ - payloadHash: components['schemas']['sha256Hash']; - /** - * Block Height - * @description The height of a block is the number of its predecessors in the block chain - * - * @example 1000000 - */ - blockHeight: number; - /** - * Block Weight - * @description The POW weight of a block is the sum of the difficulties of the block - * and of all of its ancestors. The difficulty of a block is the maximum - * difficulty divided by the target. - * - * It represented as the base64Url (without padding) 256 bit little endian - * encoding of the numerical value. - * - * @example iil_D0t2MGqjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - */ - blockWeight: string; - /** - * PoW Target - * @description The PoW target of a block represented as the base64Url (without - * padding) 256 bit little endian encoding of the numerical value. - * - * @example 2uMCnB4lWsErj9w1C1vAp1sHYd-sABf3kgcAAAAAAAA - */ - target: string; - /** - * PoW Nonce - * @description PoW nonce of the block. This is computed by the miner such that the - * block hash is smaller than the target. - */ - nonce: string; - /** - * Base64Url Block Header - * @description Base64Url (without padding) encoded binary block header - * @example { - * "value": { - * "$ref": "components[\"examples\"][\"base64HeaderPage\"][\"value\"][\"items\"][\"0\"]" - * } - * } - */ - base64Header: string; - /** Backup job status */ - backupStatus: string; - /** - * Backup job identifier - * @description Textual backup job identifier - * @example 1648665437000 - */ - backupId: string; - /** - * Binary Block Header - * @description Binary representation of a block header - */ - binaryHeader: string; - /** - * Block Header - * @description JSON Encoded Block Header - * @example { - * "value": { - * "$ref": "components[\"examples\"][\"blockHeaderPage\"][\"value\"][\"items\"][\"0\"]" - * } - * } - */ - blockHeader: { - creationTime: components['schemas']['posixTimestampMicro']; - parent: components['schemas']['blockHash']; - height: components['schemas']['blockHeight']; - hash: components['schemas']['blockHash']; - chainId: components['schemas']['chainId']; - weight: components['schemas']['blockWeight']; - /** @description A reserved value that must be 0. */ - featureFlags: number; - epochStart: components['schemas']['posixTimestampMicro']; - /** - * @description The block hashes of the adjacent parents of the block. This is - * represented as an associative array that maps the adjancent chain - * ids to the respective block hash. - */ - adjacents: { - [key: string]: components['schemas']['blockHash'] | undefined; - }; - payloadHash: components['schemas']['payloadHash']; - chainwebVersion: components['schemas']['chainwebVersion']; - target: components['schemas']['target']; - nonce: components['schemas']['nonce']; - }; - /** - * Block Payload - * @description Payload of a Block including the Merkle roots for transactions and - * transaction outputs. - * - * @example { - * "value": { - * "$ref": "components[\"examples\"][\"payloads\"][\"value\"][\"1\"]" - * } - * } - */ - payload: { - /** @description Array of base64Url (without padding) encoded JSON texts of signed Pact transactions */ - transactions: string[]; - /** @description Base64Url (without padding) encoded JSON text of the miner data of the payload */ - minerData: string; - transactionsHash: components['schemas']['sha256Hash']; - outputsHash: components['schemas']['sha256Hash']; - payloadHash: components['schemas']['payloadHash']; - }; - /** - * Block Payload With Outputs - * @description Payload with outputs of a Block including the Merkle roots for - * transactions and transaction outputs - * - * @example { - * "value": { - * "transactions": [], - * "minerData": "eyJhY2NvdW50IjoiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCIsInByZWRpY2F0ZSI6ImtleXMtYWxsIiwicHVibGljLWtleXMiOlsiYTFiMzE0MGNiN2NjODk1YzBlMDkxNzAyZWQwNTU3OWZiZTA1YzZlNjc0NWY4MmNlNjAzNzQ2YjQwMGM4MTU0OCJdfQ", - * "transactionsHash": "nT0j4xw2woMkdXXaopdurXIn24OG-jNMqQzUGfxV_MA", - * "outputsHash": "4pXRrZ2K0_V0iGAxQCKrKdLjQTBZHBOQS7P-47kdnhY", - * "payloadHash": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA", - * "coinbase": "eyJnYXMiOjAsInJlc3VsdCI6eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6IldyaXRlIHN1Y2NlZWRlZCJ9LCJyZXFLZXkiOiJJa2hoV0VGQ2NURlFTMU5MYkdodVkwcHJNRjlOZERjMVgyeE1OMDVUTTNkSk5qSTNVV1pZV2w4NE5Xc2kiLCJsb2dzIjoiZ3Noak1kWFJrVGxKYmIxalZkQWJ6SVVDcGpQb1JBQ2pEbExzRzBXNkJEMCIsIm1ldGFEYXRhIjpudWxsLCJjb250aW51YXRpb24iOm51bGwsInR4SWQiOjEyNzIzNTB9" - * } - * } - */ - payloadWithOutputs: { - /** - * @description Array of pairs of transactions and their outputs. - * Signed Pact transactions and outputs are base64Url-encoded without padding. - */ - transactions: (string | string)[][]; - /** @description Base64Url (without padding) encoded JSON text of the miner data of the payload */ - minerData: string; - transactionsHash: components['schemas']['sha256Hash']; - outputsHash: components['schemas']['sha256Hash']; - payloadHash: components['schemas']['payloadHash']; - /** @description Base64Url (without padding) encoded JSON text of coinbase output of the block */ - coinbase: string; - }; - /** - * Peer - * @description Peer info object - * @example { - * "address": { - * "hostname": "85.238.99.91", - * "port": 30004 - * }, - * "id": "PRLmVUcc9AH3fyfMYiWeC4nV2i1iHwc0-aM7iAO8h18" - * } - */ - peer: { - /** - * @description The base64Url (without padding) encoded SHA256 fingerprint of the - * SSL certificate of the node. This can be null only if the node uses - * an official CA signed certificate - */ - id: string | null; - address: { - /** - * @description A domain name or IP address. This must be a domain name only if - * the respective node is using a valid CA signed SSL certificate. - */ - hostname: - | Record - | Record - | Record; - /** @description Port number */ - port: number; - }; - }; - /** - * Cut - * @description Cut datastruction of the chainweb API - * @example { - * "value": { - * "origin": null, - * "height": 30798466, - * "weight": "b0wYplmNiTBXCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - * "hashes": { - * "0": { - * "height": 1539923, - * "hash": "qEaSmWt_tDcJC9AGbgWY9x12LW5VED7hGgfyz9x_S3w" - * }, - * "1": { - * "height": 1539923, - * "hash": "TJuC6nfhamfD517gspAZmqD9umR71nAgttDOi1JbBHw" - * }, - * "2": { - * "height": 1539924, - * "hash": "4ineCWfnO1rneWuBMLPzqTl2HF_sZpypT_3TEzf3VLc" - * }, - * "3": { - * "height": 1539924, - * "hash": "ZEOMXB2ByqzL2HfYVKIZKAnoe4wIeJ2SaltnXDir59k" - * }, - * "4": { - * "height": 1539923, - * "hash": "0g0rOoSznVW2BJDBmK0Lbxz22F-sxTZUNIrUs_Q8Ye4" - * }, - * "5": { - * "height": 1539923, - * "hash": "5y_TL-clnF_wELMBKyJk0Sz8RVShw_bGQETJdrMkADA" - * }, - * "6": { - * "height": 1539923, - * "hash": "YkQKv6P4_C4jRM3RqKK9FWPxIneeLzlkKQS9ATAQYRk" - * }, - * "7": { - * "height": 1539923, - * "hash": "j_hJ9iiH_ATyeQeeRN3auGXjbBWiFgnTU0dYPIz8cKM" - * }, - * "8": { - * "height": 1539924, - * "hash": "s7c3B55VbDsS6EJ-nc9S5k2kNbPOBGI8xxF3vUg4d4Q" - * }, - * "9": { - * "height": 1539922, - * "hash": "bowQf63xSY9owHKhK1yGee2Q0Fn8yL_oCLaEUn-CGoA" - * }, - * "10": { - * "height": 1539924, - * "hash": "uP-pHW4QKrV9fN1mlDGwKuaiIDlJW7xYSj1nW53EHM4" - * }, - * "11": { - * "height": 1539924, - * "hash": "TIhegjZ0GEC73T4m0BVuFtfLNGuS56IUWEuf93AJ5UU" - * }, - * "12": { - * "height": 1539923, - * "hash": "-j1qcAS9Fs-WQmc3WEhzZ96VojxnlIA2TFpfyIv31Zs" - * }, - * "13": { - * "height": 1539923, - * "hash": "S-4TqMgWGlK1k33XRlU9w0Lfwr0RvkO5Jn78Au1OglM" - * }, - * "14": { - * "height": 1539923, - * "hash": "xSuULf--S4TrgYNz82deaGhnPLWrg3pXkynGeUPUGwA" - * }, - * "15": { - * "height": 1539923, - * "hash": "jsc9rugvcHXDiBAuoO9_j8R_b_jchtJJ8b5596i8wVg" - * }, - * "16": { - * "height": 1539923, - * "hash": "qs1aEY8kSxfUBb_JRVswv5dYINRXBjGJteC-6RC1hjc" - * }, - * "17": { - * "height": 1539924, - * "hash": "xzVBXaQxzlUfUrakDgppUubQBRXGh-Uy0HBdMNwCq_Y" - * }, - * "18": { - * "height": 1539924, - * "hash": "4VOHPAqwioySYRycdl5MxfscQHwtlwwCAt7AySYQT98" - * }, - * "19": { - * "height": 1539923, - * "hash": "1PrRg20XyQ_2cfgGOgNK9K-cqIJ1vO8-A-RJlfN5m00" - * } - * }, - * "id": "BBz7KeurYTeQ0hMGbwUbQC84cRbVcacoDQTye-3qkXI", - * "instance": "mainnet01" - * } - * } - */ - cut: { - origin?: components['schemas']['peer']; - /** - * @description The cut height is the sum of the height of all blocks of the cut. - * Usage of this value should be avoided, because its semantics may - * change in the future - */ - height: number; - /** @description The sum of the weights of all blocks in the cut */ - weight: string; - /** - * @description An object that maps chain Ids to their respective block hash and - * block height - */ - hashes: { - [key: string]: components['schemas']['hashWithBlockHeight'] | undefined; - }; - instance?: string; - id?: string; - }; - /** - * Hash with block height - * @description A block hash and the height of that block - * @example { - * "height": 1539924, - * "hash": "uP-pHW4QKrV9fN1mlDGwKuaiIDlJW7xYSj1nW53EHM4" - * } - */ - hashWithBlockHeight: { - hash: string; - height: number; - }; - /** - * Chainweb Node Info - * @description General information about a chainweb node - * @example { - * "value": { - * "nodeNumberOfChains": 20, - * "nodeApiVersion": "0.0", - * "nodeChains": [ - * "12", - * "13", - * "14", - * "15", - * "8", - * "9", - * "10", - * "11", - * "4", - * "5", - * "6", - * "7", - * "0", - * "16", - * "1", - * "17", - * "2", - * "18", - * "3", - * "19" - * ], - * "nodeVersion": "mainnet01", - * "nodeGraphHistory": [ - * [ - * 0, - * [ - * [ - * 0, - * [ - * 5, - * 2, - * 3 - * ] - * ], - * [ - * 1, - * [ - * 4, - * 6, - * 3 - * ] - * ], - * [ - * 2, - * [ - * 4, - * 7, - * 0 - * ] - * ], - * [ - * 3, - * [ - * 8, - * 0, - * 1 - * ] - * ], - * [ - * 4, - * [ - * 9, - * 1, - * 2 - * ] - * ], - * [ - * 5, - * [ - * 9, - * 6, - * 0 - * ] - * ], - * [ - * 6, - * [ - * 5, - * 7, - * 1 - * ] - * ], - * [ - * 7, - * [ - * 8, - * 6, - * 2 - * ] - * ], - * [ - * 8, - * [ - * 9, - * 7, - * 3 - * ] - * ], - * [ - * 9, - * [ - * 8, - * 4, - * 5 - * ] - * ] - * ] - * ], - * [ - * 852054, - * [ - * [ - * 0, - * [ - * 15, - * 10, - * 5 - * ] - * ], - * [ - * 1, - * [ - * 11, - * 6, - * 16 - * ] - * ], - * [ - * 2, - * [ - * 12, - * 7, - * 17 - * ] - * ], - * [ - * 3, - * [ - * 13, - * 8, - * 18 - * ] - * ], - * [ - * 4, - * [ - * 14, - * 9, - * 19 - * ] - * ], - * [ - * 5, - * [ - * 8, - * 7, - * 0 - * ] - * ], - * [ - * 6, - * [ - * 8, - * 9, - * 1 - * ] - * ], - * [ - * 7, - * [ - * 9, - * 5, - * 2 - * ] - * ], - * [ - * 8, - * [ - * 5, - * 6, - * 3 - * ] - * ], - * [ - * 9, - * [ - * 4, - * 6, - * 7 - * ] - * ], - * [ - * 10, - * [ - * 11, - * 0, - * 19 - * ] - * ], - * [ - * 11, - * [ - * 12, - * 10, - * 1 - * ] - * ], - * [ - * 12, - * [ - * 13, - * 11, - * 2 - * ] - * ], - * [ - * 13, - * [ - * 12, - * 14, - * 3 - * ] - * ], - * [ - * 14, - * [ - * 13, - * 15, - * 4 - * ] - * ], - * [ - * 15, - * [ - * 14, - * 0, - * 16 - * ] - * ], - * [ - * 16, - * [ - * 15, - * 1, - * 17 - * ] - * ], - * [ - * 17, - * [ - * 16, - * 2, - * 18 - * ] - * ], - * [ - * 18, - * [ - * 17, - * 3, - * 19 - * ] - * ], - * [ - * 19, - * [ - * 10, - * 4, - * 18 - * ] - * ] - * ] - * ] - * ] - * } - * } - */ - nodeInfo: { - /** @example 20 */ - nodeNumberOfChains: number; - /** @example 0.0 */ - nodeApiVersion: string; - /** - * @example [ - * "0" - * ] - */ - nodeChains: string[]; - /** - * @example mainnet01 - * @enum {string} - */ - nodeVersion: 'test-singleton' | 'development' | 'mainnet01' | 'testnet04'; - /** - * @description Array of all chain graphs indexed by the height of the first block with the repective - * graph. Graphs are encoded as adjacency lists. - */ - nodeGraphHistory: (number | (number | number[])[][])[][]; - }; - /** - * Page - * @description Page of a collection of items - * @example { - * "value": { - * "next": "inclusive:o1S4NNFhKWg8T1HEkmDvsTH9Ut9l3_qHRpp00yRKZIk", - * "items": [ - * "AAAAAAAAAABRoiLHW7EFAB2lwAatTykipYZ3CZNPzLe-f5S-zUt8COtu0H12f_OZAwAFAAAAMpic85rur2MYf3zli8s8bHxTFjriFoMPTr6ZPs8sjxMKAAAAVBKuhU_hQmuvKlx88A5o-FH0rzNo59NsdxmOGNBQ-ycPAAAAMItdqgHZxf7j6l0oE8X-G9-VyMbnQmZrtSniuRe_EJ9CtyxsSb7daPIIYAaXMgSEsQ3dkxY5GjJjLwAAAAAAABqWlmx5B6wo0YWPIShNKmdVrAQWht2P85BS1drGLpkAAAAAADUJ-ARn7blgHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEIPAAAAAAAFAAAA-na5gFuxBQAFL-3CY4YuAJNGp9KhDkbrKkIPWYyq8WvtAaNPoUFWC16louSx8YN5", - * "AAAAAAAAAAA0slHKW7EFAJNGp9KhDkbrKkIPWYyq8WvtAaNPoUFWC16louSx8YN5AwAFAAAAALcxv1ZiwwQ_QX9eOBZMbzIop6n7XtveS1FqOFwyvGMKAAAAC76ElC60qXSJQCHePpzzJxsCYvvrqvmkoHPyZnex-4QPAAAAKv0sz_rTANjoiJwMrdZFCJNFwdH0U_M5ouwMr3BXBfpCtyxsSb7daPIIYAaXMgSEsQ3dkxY5GjJjLwAAAAAAALJlIg1vY3w_9L63bePn1yk_5agvdEbIBBjm3adxc5xWAAAAAGzpBzdiVL9gHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQUIPAAAAAAAFAAAA-na5gFuxBQALiBhXgqaHAb4VWug3oddEVy0X9y_jEkE2Kmi_vyGP5ovr-fDIz_Uf" - * ], - * "limit": 2 - * } - * } - */ - page: { - /** - * @description The number of items in the page. This number can be smaller but - * never be larger than the number of requested items. - */ - limit: number; - /** - * @description A cursor that can be used to query the next page. It should be used - * literally as value for the `next` parameter in a follow-up request. - */ - next: null | string; - /** @description The items in the page. */ - items: Record; - }; - /** - * Mining Update Events - * @description A stream of server-sent events. **This is not an JSON array**. - * Events are separated by empty lines (`\n\n`). Each event - * consists of a single line: - * - * event:New Cut - * - * @example event:New Cut - * - * event:New Cut - * - * event:New Cut - */ - miningUpdateEventStream: { - /** @enum {string} */ - event?: 'New Cut'; - }[]; - /** - * Miner Info - * @example { - * "account": "miner", - * "predicate": "keys-all", - * "public-keys": [ - * "f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27" - * ] - * } - */ - minerInfo: { - /** - * Account Name - * @description Miner account name. Usually this is the same as the public key. - * @example f880a433d6e2a13a32b6169030f56245efdd8c1b8a5027e9ce98a88e886bef27 - */ - account?: string; - /** - * Key Predicate - * @description key predicate. For a single key this is usually `keys-all`. - * @example keys-all - * @enum {unknown} - */ - predicate?: 'keys-all' | 'keys-any'; - 'public-keys'?: string[]; - }; - /** - * Node Configuration - * @description The configuration of a node. Private information regarding certificates - * and local networks are removed. The schema is subject to change and not - * part of the stable API. - * - * @example { - * "value": { - * "allowReadsInLocal": false, - * "rosetta": true, - * "throttling": { - * "local": 1, - * "mining": 2, - * "global": 200, - * "putPeer": 21 - * }, - * "serviceApi": { - * "interface": "invalid", - * "port": 0 - * }, - * "validateHashesOnReplay": false, - * "chainwebVersion": "mainnet01", - * "pactQueueSize": 2000, - * "mining": { - * "coordination": { - * "enabled": false, - * "updateStreamTimeout": 240, - * "limit": 1200, - * "updateStreamLimit": 2000, - * "miners": [] - * }, - * "nodeMining": { - * "miner": { - * "account": "", - * "predicate": "keys-all", - * "public-keys": [] - * }, - * "enabled": false - * } - * }, - * "p2p": { - * "peer": { - * "certificateChainFile": null, - * "key": null, - * "interface": "*", - * "certificateChain": null, - * "hostaddress": { - * "hostname": "34.70.108.163", - * "port": 1789 - * }, - * "keyFile": null - * }, - * "maxPeerCount": 100, - * "private": false, - * "ignoreBootstrapNodes": false, - * "maxSessionCount": 8, - * "bootstrapReachability": 0.5, - * "sessionTimeout": 300, - * "peers": [ - * { - * "address": { - * "hostname": "us-e1.chainweb.com", - * "port": 443 - * }, - * "id": null - * }, - * { - * "address": { - * "hostname": "us-w1.chainweb.com", - * "port": 443 - * }, - * "id": null - * } - * ] - * }, - * "transactionIndex": { - * "enabled": true, - * "configuration": {} - * }, - * "gasLimitOfBlock": 150000, - * "reorgLimit": 480, - * "headerStream": true, - * "mempoolP2p": { - * "enabled": true, - * "configuration": { - * "pollInterval": 30, - * "maxSessionCount": 6, - * "sessionTimeout": 240 - * } - * }, - * "reintroTxs": true, - * "cuts": { - * "pruneChainDatabase": "none", - * "fetchTimeout": 3000000, - * "initialCutHeightLimit": null - * } - * } - * } - */ - nodeConfig: Record; - }; - responses: {}; - parameters: { - /** - * @description Maximum number of records that may be returned. The actual number may be - * lower. - */ - limit: number; - /** - * @description The cursor for the next page. This value can be found as value of the - * `next` property of the previous page. - */ - next: string; - /** @description the id of the chain to which the request is sent */ - chain: number; - /** @description The identifier of the backup being checked */ - backupId: components['schemas']['backupId']; - /** @description Flag, if present back up the Pact databases too. Extra disk space and time required */ - backupPact: string; - /** - * @description Minimum block height of the returned headers - * @example 500000 - */ - minheight: number; - /** - * @description Maximum block height of the returned headers - * @example 500000 - */ - maxheight: number; - /** - * @description Payload hash of a block - * @example { - * "value": "GpaWbHkHrCjRhY8hKE0qZ1WsBBaG3Y_zkFLV2sYumQA" - * } - */ - payloadHash: components['schemas']['payloadHash']; - /** - * @description Block hash of a block - * @example { - * "value": [ - * "k0an0qEORusqQg9ZjKrxa-0Bo0-hQVYLXqWi5LHxg3k" - * ] - * } - */ - blockHash: components['schemas']['blockHash']; - }; - requestBodies: { - /** @description Array of request keys */ - requestKeyArray?: { - content: { - 'application/json': components['schemas']['requestKey'][]; - }; - }; - /** @description An array of block payload hashes */ - payloadHashArray?: { - content: { - 'application/json': components['schemas']['payloadHash'][]; - }; - }; - }; - headers: { - /** - * @description The time of the clock of the remote node - * @example 1618597601 - */ - 'x-server-timestamp': components['schemas']['posixTimestamp']; - /** - * @description The version of the remote chainweb node - * @example 2.6 - */ - 'x-chainweb-node-version': string; - /** - * @description Host and port of the client as observed by the remote node - * @example 10.36.1.3:42988 - */ - 'x-peer-addr': components['schemas']['hostAddress']; - }; - pathItems: never; -} - -export type external = Record; - -export type operations = Record; diff --git a/packages/libs/chainweb-node-client/src/openapi/pact.ts b/packages/libs/chainweb-node-client/src/openapi/pact.ts deleted file mode 100644 index 0a5f0c90a4..0000000000 --- a/packages/libs/chainweb-node-client/src/openapi/pact.ts +++ /dev/null @@ -1,629 +0,0 @@ -/** - * This file was auto-generated by openapi-typescript. - * Do not make direct changes to the file. - */ - -/** Type helpers */ -type Without = { [P in Exclude]?: never }; -type XOR = T | U extends object - ? (Without & U) | (Without & T) - : T | U; -type OneOf = T extends [infer Only] - ? Only - : T extends [infer A, infer B, ...infer Rest] - ? OneOf<[XOR, ...Rest]> - : never; - -export interface paths { - '/local': { - /** - * local - * @description Blocking/sync call to submit a command for non-transactional execution. In a - * blockchain environment this would be a node-local “dirty read”, which can - * either serve as a node-local repl execution, or fully gassed transaction - * simulation and transaction validation. Any database writes or changes to the - * environment are rolled back. - */ - post: { - /** - * local - * @description Blocking/sync call to submit a command for non-transactional execution. In a - * blockchain environment this would be a node-local “dirty read”, which can - * either serve as a node-local repl execution, or fully gassed transaction - * simulation and transaction validation. Any database writes or changes to the - * environment are rolled back. - */ - parameters?: { - /** - * @description Trigger fully-gassed mainnet transaction execution simulation and - * transaction metadata validations. - */ - /** - * @description Require user signature validation when validating transaction - * metadata. - */ - query?: { - preflight?: Record; - signatureValidation?: Record; - }; - }; - requestBody?: { - content: { - 'application/json': components['schemas']['command']; - }; - }; - responses: { - /** @description The command's result. */ - 200: { - content: { - 'application/json': components['schemas']['command-result']; - }; - }; - /** @description The command was invalid. */ - 400: { - content: { - 'text/plain': components['schemas']['validation-failure']; - }; - }; - }; - }; - }; - '/send': { - /** - * send - * @description Asynchronous submission of one or more public (unencrypted) commands - * to the blockchain for execution. - */ - post: { - /** - * send - * @description Asynchronous submission of one or more public (unencrypted) commands - * to the blockchain for execution. - */ - requestBody?: { - content: { - 'application/json': { - cmds: components['schemas']['command'][]; - }; - }; - }; - responses: { - /** @description The commands were successfully submitted. The response contains their request keys. */ - 200: { - content: { - 'application/json': { - /** @description Request keys for use with `poll` or `listen` to retrieve results. */ - requestKeys: components['schemas']['request-key'][]; - }; - }; - }; - /** @description The command failed. */ - 400: { - content: { - 'text/plain': components['schemas']['validation-failure']; - }; - }; - }; - }; - }; - '/poll': { - /** - * poll - * @description Allows polling for one or more command results by request key. - */ - post: { - /** - * poll - * @description Allows polling for one or more command results by request key. - */ - requestBody?: { - content: { - 'application/json': { - requestKeys: components['schemas']['request-key'][]; - }; - }; - }; - responses: { - /** @description The command results for some of the requested request keys. */ - 200: { - content: { - 'application/json': { - [key: string]: - | components['schemas']['command-result'] - | undefined; - }; - }; - }; - }; - }; - }; - '/listen': { - /** - * listen - * @description Blocking request for single command result. - */ - post: { - /** - * listen - * @description Blocking request for single command result. - */ - requestBody?: { - content: { - 'application/json': { - listen: components['schemas']['request-key']; - }; - }; - }; - responses: { - /** @description The request key was found. */ - 200: { - content: { - 'application/json': components['schemas']['command-result']; - }; - }; - }; - }; - }; - '/private': { - /** - * private - * @description Asynchronous submission of a single addressed command which - * will be transmitted with end-to-end encryption only between addressed entity nodes. - * Private payload metadata required. - */ - post: { - /** - * private - * @description Asynchronous submission of a single addressed command which - * will be transmitted with end-to-end encryption only between addressed entity nodes. - * Private payload metadata required. - */ - requestBody?: { - content: { - 'application/json': components['schemas']['command']; - }; - }; - responses: { - /** @description The command was accepted. */ - 200: { - content: { - 'application/json': { - /** @description Request keys for use with `poll` or `listen` to retrieve results. */ - requestKeys?: components['schemas']['request-key'][]; - }; - }; - }; - }; - }; - }; - '/spv': { - /** - * spv - * @description Blocking request to fetch spv proof of a cross chain transaction. Request must be sent to the chain where the transaction is initiated. - */ - post: { - /** - * spv - * @description Blocking request to fetch spv proof of a cross chain transaction. Request must be sent to the chain where the transaction is initiated. - */ - requestBody?: { - content: { - 'application/json': components['schemas']['spv-object']; - }; - }; - responses: { - /** @description The requested spv proof. */ - 200: { - content: { - 'application/json': components['schemas']['spv-proof']; - }; - }; - /** @description The requested spv proof was not findable. */ - 400: { - content: { - 'text/plain': string; - }; - }; - }; - }; - }; -} - -export type webhooks = Record; - -export interface components { - schemas: { - /** - * Pact Command - * @description Represents a single blockchain Pact transaction. - * @example { - * "hash": "H6XjdPHzMai2HLa3_yVkXfkFYMgA0bGfsB0kOsHAMuI", - * "sigs": [ - * { - * "sig": "8d452109cc0439234c093b5e204a7428bc0a54f22704402492e027aaa9375a34c910d8a468a12746d0d29e9353f4a3fbebe920d63bcc7963853995db015d060f" - * } - * ], - * "cmd": "{\"payload\":{\"exec\":{\"data\":null,\"code\":\"(+ 1 2)\"}},\"signers\":[{\"pubKey\":\"368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca\"}],\"meta\":{\"gasLimit\":1000,\"chainId\":\"0\",\"gasPrice\":1.0e-2,\"sender\":\"368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca\"},\"nonce\":\"nonce-value\"}" - * } - */ - command: { - /** @description Stringified JSON `payload` object. Canonic non-malleable signed transaction data. */ - cmd: string; - /** - * @description Unpadded Base64URL of Blake2s-256 hash of the `cmd` field value. Serves as a command - * `requestKey` since each transaction must be unique. - * - * @example H6XjdPHzMai2HLa3_yVkXfkFYMgA0bGfsB0kOsHAMuI - */ - hash: string; - /** @description List of signatures corresponding one-to-one with `signers` array in the payload. */ - sigs: { - /** - * @description Base16-encoded cryptograhic signature of `cmd` field data - * for corresponding signer in payload. - * - * @example 8d452109cc0439234c093b5e204a7428bc0a54f22704402492e027aaa9375a34c910d8a468a12746d0d29e9353f4a3fbebe920d63bcc7963853995db015d060f - */ - sig?: string; - }[]; - }; - /** - * @description Pact Command Payloads are encoded as strings in Pact commands, and contain all - * non-malleable data for a transaction. - * - * @example { - * "payload": { - * "exec": { - * "data": null, - * "code": "(coin.transfer \"Alice\" \"Bob\" 10.0)" - * } - * }, - * "signers": [ - * { - * "pubKey": "368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca", - * "clist": [ - * { - * "name": "coin.TRANSFER", - * "args": [ - * "Alice", - * "Bob", - * 10 - * ] - * } - * ] - * } - * ], - * "meta": { - * "gasLimit": 1000, - * "chainId": "0", - * "gasPrice": 0.01, - * "sender": "368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca" - * }, - * "nonce": "nonce-value" - * } - */ - payload: { - payload: OneOf< - [ - { - /** @description Executable pact code. */ - code?: string; - /** @description Arbitrary JSON to be accessed via `read-msg`, `read-integer` et al in Pact code. */ - data?: Record; - }, - { - /** @description ID of pact running previous step. */ - pactId?: string; - /** @description Step in defpact to execute. */ - step?: number; - /** @description Whether to execute a specified rollback on this step. */ - rollback?: boolean; - /** @description Arbitrary JSON to be accessed via `read-msg`, `read-integer` et al in Pact code. */ - data?: Record; - /** @description Backend-specific data for continuing a cross-chain proof. */ - proof?: string; - }, - ] - >; - meta: OneOf< - [ - { - /** @description Platform-specific chain identifier. For chainweb this is the stringified chain number. */ - chainId: string; - /** @description Indicates gas-paying account. */ - sender: string; - /** @description Limits total amount of gas to be consumed. */ - gasLimit: number; - /** @description Specifies price per gas unit to be charged. */ - gasPrice: number; - /** @description Time in seconds after creation time that transaction can be executed. */ - ttl: number; - /** @description POSIX epoch sending time for transaction. */ - creationTime: number; - }, - { - /** @description Private message envelope address. Required only for private messages, otherwise null. */ - address?: { - /** @description Sender entity name */ - from: string; - /** @description Recipient entity names */ - to: string[]; - }; - }, - ] - >; - /** @description List of signers, corresponding with list of signatures in outer command. */ - signers: { - /** @description Public key image. Pact default is base16 ED25519 encoding. */ - pubKey: string; - /** @description Address, if any. Pact default expects this to match pubKey. */ - address?: string; - /** - * @description Signer scheme. Default is ED25519. - * @enum {string} - */ - scheme?: 'ED25519' | 'ETH'; - /** @description List of capabilities associated with/installed by this signer. */ - clist?: { - /** @description Fully-qualified capability name. */ - name?: string; - args?: components['schemas']['pact-value'][]; - }; - }[]; - /** - * @description Backend-specific identifier of target network. - * @enum {string} - */ - networkId: 'mainnet01' | 'testnet04'; - /** @description Arbitrary user-supplied value. */ - nonce: string; - }; - /** @description Object consisting of data required to fetch proof of a cross chain transaction */ - 'spv-object': { - /** - * @description Request Key of an initiated cross chain transaction at the source chain. - * @example 7af34f24d55d2fcf5de6fccfeeb837698ebff4598303237c64348a47806c8646 - */ - requestKey: string; - /** - * @description Target chain id of the cross chain transaction. - * @example 1 - */ - targetChainId: string; - }; - /** - * Command Result - * @description The result of attempting to execute a single well-formed Pact command. - * @example { - * "gas": 123, - * "result": { - * "status": "success", - * "data": 3 - * }, - * "reqKey": "cQ-guhschk0wTvMBtrqc92M7iYm4S2MYhipQ2vNKxoI", - * "logs": "wsATyGqckuIvlm89hhd2j4t6RMkCrcwJe_oeCYr7Th8", - * "metaData": null, - * "continuation": null, - * "txId": "456", - * "events": [ - * { - * "name": "TRANSFER", - * "params": [ - * "Alice", - * "Bob", - * 10 - * ], - * "module": "coin", - * "moduleHash": "ut_J_ZNkoyaPUEJhiwVeWnkSQn9JT9sQCWKdjjVVrWo" - * } - * ] - * } - */ - 'command-result': { - reqKey: components['schemas']['request-key']; - result: OneOf< - [ - { - /** @enum {string} */ - status?: 'success'; - data?: components['schemas']['pact-value']; - }, - { - /** @enum {string} */ - status?: 'failure'; - error?: components['schemas']['pact-error']; - }, - ] - >; - /** @description Database-internal transaction tracking ID. */ - txId?: number; - /** @description Backend-specific value providing image of database logs. */ - logs: string; - metaData: { - /** @description POSIX time of block */ - blockTime?: number; - /** @description Parent Block hash of containing block. */ - prevBlockHash?: string; - /** @description Block hash of containing block. */ - blockHash?: string; - /** @description Block height of containing block. */ - blockHeight?: number; - /** @description Public metadata. */ - publicMeta?: { - /** @description POSIX time the command was created */ - creationTime?: number; - /** @description Transaction time to live */ - ttl?: number; - /** @description The transaction's gas limit */ - gasLimit?: number; - /** @description Chain identifier */ - chainId?: string; - /** @description The price of each unit of gas in KDA */ - gasPrice?: number; - sender?: string; - }; - }; - events?: components['schemas']['event'][]; - /** @description Describes result of a defpact execution. */ - continuation?: { - /** @description Identifies this defpact execution. On first step generally matches request key. */ - pactId?: string; - /** @description Identifies which step executed in defpact. */ - step?: number; - /** @description Total number of steps in pact. */ - stepCount?: number; - /** @description optional value for private pacts, indicates if step was skipped. */ - executed?: boolean; - /** @description indicates if pact step has rollback. */ - stepHasRollback?: boolean; - /** @description Closure describing executed pact. */ - continuation?: { - /** @description Fully-qualified defpact name. */ - def?: string; - args?: components['schemas']['pact-value'][]; - }; - /** @description Value yielded during pact step, optionally indicating cross-chain execution. */ - yield?: { - /** @description Pact value object containing yielded data. */ - data?: { - [key: string]: components['schemas']['pact-value'] | undefined; - }; - /** @description Source chain ID. */ - source?: string; - provenance?: { - /** @description Chain ID of target chain for next step. */ - targetChainId?: string; - /** @description Hash of module executing defpact. */ - moduleHash?: string; - }; - }; - }; - gas: number; - }; - /** @description Pact value compound type. */ - 'pact-value': - | string - | OneOf< - [ - number, - { - /** - * @description String representation of number to avoid rounding error - * @example 1.23498218000001 - */ - decimal: string; - }, - ] - > - | { - int: number | string; - } - | boolean - | { - [key: string]: components['schemas']['pact-value'] | undefined; - } - | { - /** - * @description Literal time value using the UTC time format. - * @example 1970-01-01T00:00:00Z - */ - time: string; - } - | components['schemas']['pact-value'][] - | { - /** @description Fully-qualified module or interface name. */ - refName?: string; - } - | OneOf< - [ - { - /** @description Set of public key/address values. Native pact public keys are ED25519 in base16 encoding. */ - keys: string[]; - /** - * @description A pact function name. Built-in values are `keys-all` (match all keys in set), - * `keys-any` (match at least one), and `keys-2` (match at least 2). - * Custom functions have a fully-qualified name and - * must accept two integer arguments `count` (number of keys in set) and `matched` - * (number of set keys found in transaction set). - */ - pred: string; - }, - { - /** @description Installed keyset name. */ - keysetref: string; - }, - { - /** @description Fully-qualified guard function name. */ - fun: string; - /** @description Argument values to the guard function. */ - args: components['schemas']['pact-value'][]; - }, - { - moduleName: { - /** @description module bare name */ - name: string; - /** @description module namespace */ - namespace: string; - }; - /** @description Distinguishing/informative name for module guard. */ - name: string; - }, - { - /** @description Defpact execution ID. */ - pactId: string; - /** @description Distinguishing/informative name for pact guard. */ - name: string; - }, - ] - >; - /** @description Pact output event. */ - event: { - /** @description Event defcap name. */ - name?: string; - /** @description Qualified module name of event defcap. */ - module?: { - /** @description module bare name */ - name: string; - /** @description module namespace */ - namespace?: string; - }; - params?: components['schemas']['pact-value'][]; - /** @description Hash of emitting module. */ - moduleHash?: string; - }; - /** @description Verbose object describing failed execution. */ - 'pact-error': { - /** @description Descriptive error text. */ - message: string; - callStack?: string[]; - info?: string; - type?: string; - }; - /** - * Request Key - * @description Unique ID of a pact transaction consisting of its hash. - * @example y3aWL72-3wAy7vL9wcegGXnstH0lHi-q-cfxkhD5JCw - */ - 'request-key': string; - /** - * Validation Failure - * @description Failure message of unexecuted command due to an invalid gas payer, meta, or other environments. - */ - 'validation-failure': string; - /** - * SPV Proof - * @description Backend-specific data for continuing a cross-chain proof. - * @example "eyJzdWJqZWN0Ijp7ImlucHV0IjoiQUJSN0ltZGhjeUk2TlRRMExDSnlaWE4xYkhRaU9uc2ljM1JoZEhWeklqb2ljM1ZqWTJWemN5SXNJbVJoZEdFaU9pSlhjbWwwWlNCemRXTmpaV1ZrWldRaWZTd2ljbVZ4UzJWNUlqb2lZa0Y0TjNOd1dqZFdUbUpZWTNocVZFUkNTamt5U21SdlUyVlFjWGx0U25KNWNXOUNhMWcyUkVoYWJ5SXNJbXh2WjNNaU9pSnBRVTF4Y0ZwaVUxSkRaR2hQUzA1YVVYZzFTMHBOTFZOUlNGRlZXRzF4UlZoUlRIRkNUVVpSVFVkSklpd2laWFpsYm5SeklqcGJleUp3WVhKaGJYTWlPbHNpZEdWemRDMXpaVzVrWlhJaUxDSXpaRGxsT1dZeFptSTBZemt6TnpneU5qWmpZV1JrTmpObE4yRTBOMkkzWVRZME5UTmlaVGsyTVdSaU1ETTNNMlkxWXpWbVlUUXdZV05sWlRaaVpHVm1JaXd4WFN3aWJtRnRaU0k2SWxSU1FVNVRSa1ZTSWl3aWJXOWtkV3hsSWpwN0ltNWhiV1Z6Y0dGalpTSTZiblZzYkN3aWJtRnRaU0k2SW1OdmFXNGlmU3dpYlc5a2RXeGxTR0Z6YUNJNkluVjBYMHBmV2s1cmIzbGhVRlZGU21ocGQxWmxWMjVyVTFGdU9VcFVPWE5SUTFkTFpHcHFWbFp5VjI4aWZWMHNJbTFsZEdGRVlYUmhJanB1ZFd4c0xDSmpiMjUwYVc1MVlYUnBiMjRpT201MWJHd3NJblI0U1dRaU9qRXhOams1TkRaOSJ9LCJhbGdvcml0aG0iOiJTSEE1MTJ0XzI1NiIsIm9iamVjdCI6IkFBQUFFQUFBQUFBQUFBQUJBUGhpTkRUdEFHT0l4dWE4OTFYUGU0NVFRS2QtTFdOekNpc0JDeHlmeDliQ0FPUkRnUUR2RFRrWmdOTzZ2M1ZpbU1wZ2ZGd2kyQm1mZ29jRVdwVmxRRW9EQWVoT1JPeFdBckJidXpldnZLTUdQZTB1RlVfUE8yejM3VC0tY0thdDZ1d3pBVm9DbFVrU1lXaXRDODF0TERVd2JYYVFWRTdnZFp1ckN6d0RiZUlBdlpBcUFKVThWZHZkMS1nYmo2UEtIVXdWQm00UWRvNl9YUkpYdHdKTGE4a0N3OWJhQWQtbXRubnlsUkczOC1WcTZzZmlZWm0xd2tKejhZcU5ZT2gwbVZCTktFR1VBTkdQWlB4NGFhMWFDdTJ1Ty1VRkJXLWxLbFdFeFU0a2JjMkszOFZCT21ZeEFDakxpdjMwazdBaGdwVXBCWUIxcEYwWFRqTmU4d3k4aHQta2FveFFKbTZpQVlXSkFYZlpXZERNdkQ3Z1UydUItWFdTVUh3bVpvM3NzV0stRzh1OTIxempBTzllbVBkOFJRVk5jOWZWZWJHN0lMb2lqVDlYMm9Db1p2Q00xQ29yR3laUUFTLVVZd3c4dkJ1bEVVYXlxaHZEQUFreUthbHk1TXk1bzJYVXZpZlZsNkg5QUM5ZXZsczVxMXh2bGhQbE9UWnJZNVB2SDNFbDd3dTBZTTJQYmZzaE1lUGFBUFpZRFJoWncyXzBVM1hIZllQbmJ6QlQ4bkc3a2gtR09kRTBTcFFCNEVOQ0FVWGEzcGVoMnhVd2dCVHd5WFVvc3RDRjNqQ21Scm9ZRGlEUTVGTGhYNkVQQUdlMUF2cFhJazZFM2tpdnUxY1N4aVFYV0hUcW1pdEUwLTVYaVpjNU4zQ3ZBS1dMNmM1RDdQSV84aW0zbG04cWhtZl84UXp3d2ZFcVpXQXZoQ0dWc1VVdCIsImNoYWluIjoxfQ" - */ - 'spv-proof': string; - }; - responses: never; - parameters: never; - requestBodies: never; - headers: never; - pathItems: never; -} - -export type external = Record; - -export type operations = Record; From 500aae29a25fedb27f1edcc91a9f535b76b2b72e Mon Sep 17 00:00:00 2001 From: Albert G <516972+alber70g@users.noreply.github.com> Date: Fri, 24 Feb 2023 15:59:43 +0100 Subject: [PATCH 33/35] chore: add type to differentiate between quicksign success and response --- packages/libs/client/etc/client.api.md | 69 +++++++++---------- .../client/src/interfaces/IPactCommand.ts | 2 +- packages/libs/client/src/pact.ts | 35 +++++++--- .../client/src/signing-api/v1/quicksign.ts | 39 ++++++----- .../client/src/signing/signWithChainweaver.ts | 8 ++- .../signing/tests/signWithChainweaver.test.ts | 11 +-- 6 files changed, 91 insertions(+), 73 deletions(-) diff --git a/packages/libs/client/etc/client.api.md b/packages/libs/client/etc/client.api.md index a484b09bf5..10a89c4ab1 100644 --- a/packages/libs/client/etc/client.api.md +++ b/packages/libs/client/etc/client.api.md @@ -7,7 +7,6 @@ import { ChainId } from '@kadena/types'; import { ChainwebNetworkId } from '@kadena/types'; import { ICap } from '@kadena/types'; -import { ICommand } from '@kadena/types'; import { ICommandResult } from '@kadena/types'; import { IPollResponse } from '@kadena/types'; import { ISendResponse } from '@kadena/chainweb-node-client'; @@ -79,7 +78,7 @@ export interface ICommandBuilder, TArgs exte sig: string; }[]): ICommandBuilder & IPactCommand; // (undocumented) - createCommand(): ICommand; + createCommand(): IUnsignedTransaction; // (undocumented) local(apiHost: string): Promise; // (undocumented) @@ -148,19 +147,6 @@ export interface IPublicMeta { ttl: number; } -// @alpha (undocumented) -export interface IQuicksignError { - // (undocumented) - error: { - type: 'reject'; - } | { - type: 'emptyList'; - } | { - type: 'other'; - msg: string; - }; -} - // @alpha (undocumented) export interface IQuickSignRequestBody { // (undocumented) @@ -168,33 +154,44 @@ export interface IQuickSignRequestBody { } // @alpha (undocumented) -export interface IQuicksignResponse { +export type IQuicksignResponse = IQuicksignResponseError | IQuicksignResponseOutcomes; + +// @alpha (undocumented) +export interface IQuicksignResponseCommand { // (undocumented) - commandSigData: IQuicksignResponseCommand; + cmd: string; // (undocumented) - outcome: { - hash: string; - result: 'success'; - } | { - msg: string; - result: 'failure'; - } | { - result: 'noSig'; - }; + sigs: IQuicksignSigner[]; } // @alpha (undocumented) -export interface IQuicksignResponseBody { +export interface IQuicksignResponseError { // (undocumented) - responses: IQuicksignResponse[]; + error: { + type: 'reject'; + } | { + type: 'emptyList'; + } | { + type: 'other'; + msg: string; + }; } // @alpha (undocumented) -export interface IQuicksignResponseCommand { - // (undocumented) - cmd: string; - // (undocumented) - sigs: IQuicksignSigner[]; +export interface IQuicksignResponseOutcomes { + // (undocumented) + responses: { + commandSigData: IQuicksignResponseCommand; + outcome: { + hash: string; + result: 'success'; + } | { + msg: string; + result: 'failure'; + } | { + result: 'noSig'; + }; + }[]; } // @alpha (undocumented) @@ -231,9 +228,7 @@ export interface IUnsignedTransaction { // (undocumented) hash: string; // (undocumented) - sigs: { - [pubkey: string]: string | undefined; - }; + sigs: (ISignature | undefined)[]; } // @alpha (undocumented) @@ -260,7 +255,7 @@ export class PactCommand implements IPactCommand, ICommandBuilder; local(apiHost: string): Promise; diff --git a/packages/libs/client/src/interfaces/IPactCommand.ts b/packages/libs/client/src/interfaces/IPactCommand.ts index 586956e53a..117a3f8f9c 100644 --- a/packages/libs/client/src/interfaces/IPactCommand.ts +++ b/packages/libs/client/src/interfaces/IPactCommand.ts @@ -36,6 +36,6 @@ export interface IPublicMeta { */ export interface IUnsignedTransaction { hash: string; - sigs: { [pubkey: string]: string | undefined }; + sigs: (ISignature | undefined)[]; cmd: string; } diff --git a/packages/libs/client/src/pact.ts b/packages/libs/client/src/pact.ts index c6458dfd24..e15d662382 100644 --- a/packages/libs/client/src/pact.ts +++ b/packages/libs/client/src/pact.ts @@ -13,7 +13,7 @@ import { PactValue, } from '@kadena/types'; -import { IPactCommand } from './interfaces/IPactCommand'; +import { IPactCommand, IUnsignedTransaction } from './interfaces/IPactCommand'; import { parseType } from './utils/parseType'; import debug, { Debugger } from 'debug'; @@ -27,7 +27,7 @@ export interface ICommandBuilder< TCaps extends Record, TArgs extends Array = TCaps[keyof TCaps], > { - createCommand(): ICommand; + createCommand(): IUnsignedTransaction; addData: ( data: IPactCommand['data'], ) => ICommandBuilder & IPactCommand; @@ -188,7 +188,7 @@ export class PactCommand * @returns a command that can be send to the blockchain * (see https://api.chainweb.com/openapi/pact.html#tag/endpoint-send/paths/~1send/post) */ - public createCommand(): ICommand { + public createCommand(): IUnsignedTransaction { const dateInMs: number = Date.now(); // convert to IUnsignedTransactionCommand @@ -217,11 +217,10 @@ export class PactCommand // hash command const hash = blakeHash(cmd); - // convert to IUnsignedTransaction - const command: ICommand = { + // TODO: convert to IUnsignedTransaction + const command: IUnsignedTransaction = { hash, - // eslint-disable-next-line @rushstack/no-new-null - sigs: this.sigs.map((s) => ({ sig: s?.sig ?? null })), + sigs: this.sigs, cmd, }; @@ -297,7 +296,10 @@ export class PactCommand public local(apiHost: string): Promise { log(`calling local with: ${JSON.stringify(this.createCommand(), null, 2)}`); - return local(this.createCommand(), apiHost); + return local( + convertIUnsignedTransactionToICommand(this.createCommand()), + apiHost, + ); } /** @@ -383,7 +385,10 @@ export class PactCommand * @alpha */ public async send(apiHost: string): Promise { - const sendResponse = await send({ cmds: [this.createCommand()] }, apiHost); + const sendResponse = await send( + { cmds: [convertIUnsignedTransactionToICommand(this.createCommand())] }, + apiHost, + ); this.requestKey = sendResponse.requestKeys[0].toString(); return sendResponse; } @@ -423,6 +428,18 @@ export class PactCommand // } } +function convertIUnsignedTransactionToICommand({ + cmd, + hash, + sigs, +}: IUnsignedTransaction): ICommand { + return { + cmd, + hash, + sigs: sigs.map((s) => ({ sig: s?.sig ?? null })), + }; +} + /** * @alpha */ diff --git a/packages/libs/client/src/signing-api/v1/quicksign.ts b/packages/libs/client/src/signing-api/v1/quicksign.ts index 8f3f3be38d..c8e41d6e45 100644 --- a/packages/libs/client/src/signing-api/v1/quicksign.ts +++ b/packages/libs/client/src/signing-api/v1/quicksign.ts @@ -30,32 +30,35 @@ export type IQuicksignSig = string | null; /** * @alpha */ -export interface IQuicksignResponseBody { - responses: IQuicksignResponse[]; -} +export type IQuicksignResponse = + | IQuicksignResponseError + | IQuicksignResponseOutcomes; + /** * @alpha */ -export interface IQuicksignResponse { - commandSigData: IQuicksignResponseCommand; - outcome: - | { - hash: string; - result: 'success'; - } - | { - msg: string; - result: 'failure'; - } - | { - result: 'noSig'; - }; +export interface IQuicksignResponseOutcomes { + responses: { + commandSigData: IQuicksignResponseCommand; + outcome: + | { + hash: string; + result: 'success'; + } + | { + msg: string; + result: 'failure'; + } + | { + result: 'noSig'; + }; + }[]; } /** * @alpha */ -export interface IQuicksignError { +export interface IQuicksignResponseError { error: | { type: 'reject'; diff --git a/packages/libs/client/src/signing/signWithChainweaver.ts b/packages/libs/client/src/signing/signWithChainweaver.ts index 3d2f240564..84d8caa2d0 100644 --- a/packages/libs/client/src/signing/signWithChainweaver.ts +++ b/packages/libs/client/src/signing/signWithChainweaver.ts @@ -47,9 +47,11 @@ export async function signWithChainweaver( // response is not JSON when not-ok, that's why we use try-catch try { - const result = JSON.parse(bodyText) as { - responses: IQuicksignResponse[]; - }; + const result = JSON.parse(bodyText) as IQuicksignResponse; + + if ('error' in result) { + throw new Error(); + } result.responses.map((signedCommand, i) => { transactions[i].addSignatures( diff --git a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts index 380b4a521a..e2236bf59c 100644 --- a/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts +++ b/packages/libs/client/src/signing/tests/signWithChainweaver.test.ts @@ -4,11 +4,12 @@ jest.mock('cross-fetch', () => { default: jest.fn(), }; }); + import { IPactCommand } from '../../interfaces/IPactCommand'; import { ICommandBuilder, Pact } from '../../pact'; import { IQuicksignResponse, - IQuicksignResponseBody, + IQuicksignResponseOutcomes, } from '../../signing-api/v1/quicksign'; import { signWithChainweaver } from '../signWithChainweaver'; @@ -20,7 +21,7 @@ describe('signWithChainweaver', () => { it('makes a call on 127.0.0.1:9467/v1/quicksign with transaction', async () => { (fetch as jest.Mock).mockResolvedValue({ status: 200, - text: () => JSON.stringify({ responses: [] } as IQuicksignResponseBody), + text: () => JSON.stringify({ responses: [] } as IQuicksignResponse), json: () => {}, }); @@ -80,7 +81,7 @@ describe('signWithChainweaver', () => { }); it('adds signatures in multisig fashion to the transactions', async () => { - const mockedResponse: { responses: IQuicksignResponse[] } = { + const mockedResponse: IQuicksignResponseOutcomes = { responses: [ { commandSigData: { @@ -117,7 +118,7 @@ describe('signWithChainweaver', () => { expect(unsignedCommand.sigs).toEqual([{ sig: 'gas-key-sig' }, undefined]); // set a new mock response for the second signature - const mockedResponse2: { responses: IQuicksignResponse[] } = { + const mockedResponse2: IQuicksignResponseOutcomes = { responses: [ { commandSigData: { @@ -146,7 +147,7 @@ describe('signWithChainweaver', () => { }); it('signs but does not have the signer key and returns sig null', async () => { - const mockedResponse: { responses: IQuicksignResponse[] } = { + const mockedResponse: IQuicksignResponseOutcomes = { responses: [ { commandSigData: { From a9fc845f6980de5175de981b8e02b210b5b1a252 Mon Sep 17 00:00:00 2001 From: Albert G <516972+alber70g@users.noreply.github.com> Date: Fri, 24 Feb 2023 16:11:11 +0100 Subject: [PATCH 34/35] fix(client): test with order when converting unsignedTransaction to ICommand --- packages/libs/client/src/pact.ts | 13 ++-- packages/libs/client/src/tests/pact.test.ts | 74 +++++---------------- 2 files changed, 22 insertions(+), 65 deletions(-) diff --git a/packages/libs/client/src/pact.ts b/packages/libs/client/src/pact.ts index e15d662382..fd057d4985 100644 --- a/packages/libs/client/src/pact.ts +++ b/packages/libs/client/src/pact.ts @@ -428,15 +428,12 @@ export class PactCommand // } } -function convertIUnsignedTransactionToICommand({ - cmd, - hash, - sigs, -}: IUnsignedTransaction): ICommand { +function convertIUnsignedTransactionToICommand( + transaction: IUnsignedTransaction, +): ICommand { return { - cmd, - hash, - sigs: sigs.map((s) => ({ sig: s?.sig ?? null })), + ...transaction, + sigs: transaction.sigs.map((s) => ({ sig: s?.sig ?? null })), }; } diff --git a/packages/libs/client/src/tests/pact.test.ts b/packages/libs/client/src/tests/pact.test.ts index 4754dd11ad..f7a50df7a8 100644 --- a/packages/libs/client/src/tests/pact.test.ts +++ b/packages/libs/client/src/tests/pact.test.ts @@ -7,7 +7,7 @@ jest.mock('cross-fetch', () => { import { PactNumber } from '@kadena/pactjs'; import { IUnsignedTransaction } from '../interfaces/IPactCommand'; -import { ICommandBuilder, Pact, PactCommand } from '../pact'; +import { Pact, PactCommand } from '../pact'; import fetch from 'cross-fetch'; @@ -152,13 +152,8 @@ describe('Pact proxy', () => { json: () => {}, }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const pact = Pact as any; - const builder: ICommandBuilder<{}> = pact.modules.coin.transfer( - 'from', - 'to', - { decimal: '1.234' }, - ); + const builder = new PactCommand(); + builder.code = '(coin.transfer "from" "to" 1.234)'; await builder.local('fake-api-host.local.co'); const body = builder.createCommand(); @@ -178,13 +173,8 @@ describe('Pact proxy', () => { json: () => ({ requestKeys: ['key1'] }), }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const pact = Pact as any; - const builder: ICommandBuilder<{}> = pact.modules.coin.transfer( - 'from', - 'to', - { decimal: '1.234' }, - ); + const builder = new PactCommand(); + builder.code = '(coin.transfer "from" "to" 1.234)'; await builder.send('fake-api-host.local.co'); const body = { cmds: [builder.createCommand()] }; @@ -204,13 +194,8 @@ describe('Pact proxy', () => { json: () => ({ requestKeys: ['key1'] }), }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const pact = Pact as any; - const builder: ICommandBuilder<{}> = pact.modules.coin.transfer( - 'from', - 'to', - { decimal: '1.234' }, - ); + const builder = new PactCommand(); + builder.code = '(coin.transfer "from" "to" 1.234)'; const { requestKeys } = await builder.send('fake-api-host.local.co'); const body = { cmds: [builder.createCommand()] }; @@ -237,13 +222,8 @@ describe('Pact proxy', () => { json: () => ({ requestKeys: ['key1'] }), }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const pact = Pact as any; - const builder: ICommandBuilder<{}> = pact.modules.coin.transfer( - 'from', - 'to', - { decimal: '1.234' }, - ); + const builder = new PactCommand(); + builder.code = '(coin.transfer "from" "to" 1.234)'; expect(() => builder.poll('fake-api-host.local.co')).toThrow(); }); @@ -256,13 +236,8 @@ describe('Pact proxy', () => { json: () => ({ requestKeys: ['key1'] }), }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const pact = Pact as any; - const builder: ICommandBuilder<{}> = pact.modules.coin.transfer( - 'from', - 'to', - { decimal: '1.234' }, - ); + const builder = new PactCommand(); + builder.code = '(coin.transfer "from" "to" 1.234)'; let expectingError; @@ -278,13 +253,8 @@ describe('Pact proxy', () => { it('returns a response after polling a succeeding transaction', async () => { jest.useFakeTimers(); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const pact = Pact as any; - const builder: ICommandBuilder<{}> = pact.modules.coin.transfer( - 'from', - 'to', - { decimal: 1.234 }, - ); + const builder = new PactCommand(); + builder.code = '(coin.transfer "from" "to" 1.234)'; (fetch as jest.Mock).mockResolvedValue({ status: 200, @@ -330,13 +300,8 @@ describe('Pact proxy', () => { it('rejects the promise for pollUntil if the transaction failed', async () => { jest.useFakeTimers(); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const pact = Pact as any; - const builder: ICommandBuilder<{}> = pact.modules.coin.transfer( - 'from', - 'to', - { decimal: 1.234 }, - ); + const builder = new PactCommand(); + builder.code = '(coin.transfer "from" "to" 1.234)'; (fetch as jest.Mock).mockResolvedValue({ status: 200, @@ -381,13 +346,8 @@ describe('Pact proxy', () => { json: () => ({ requestKeys: ['key1'] }), }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const pact = Pact as any; - const builder: ICommandBuilder<{}> = pact.modules.coin.transfer( - 'from', - 'to', - { decimal: 1.234 }, - ); + const builder = new PactCommand(); + builder.code = '(coin.transfer "from" "to" 1.234)'; await builder.send('fake-api-host.local.co'); From cf51b6c7b20459d0d3cc8f6e8f0512e18fd1dc3b Mon Sep 17 00:00:00 2001 From: ggobugi27 Date: Mon, 27 Feb 2023 21:43:51 +0900 Subject: [PATCH 35/35] add test coverage --- packages/libs/client/etc/client.api.md | 4 ++ packages/libs/client/src/pact.ts | 5 ++- packages/libs/client/src/tests/pact.test.ts | 45 ++++++++++++++++++++- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/packages/libs/client/etc/client.api.md b/packages/libs/client/etc/client.api.md index 10a89c4ab1..78472ae8bf 100644 --- a/packages/libs/client/etc/client.api.md +++ b/packages/libs/client/etc/client.api.md @@ -7,6 +7,7 @@ import { ChainId } from '@kadena/types'; import { ChainwebNetworkId } from '@kadena/types'; import { ICap } from '@kadena/types'; +import { ICommand } from '@kadena/types'; import { ICommandResult } from '@kadena/types'; import { IPollResponse } from '@kadena/types'; import { ISendResponse } from '@kadena/chainweb-node-client'; @@ -21,6 +22,9 @@ export function buildCommandFromTemplate(parts: string[], holes: string[], args: // @internal (undocumented) export function buildUnsignedTransaction(parts: string[], holes: string[], args: Record): IPactCommand & ICommandBuilder<{}>; +// @alpha (undocumented) +export function convertIUnsignedTransactionToICommand(transaction: IUnsignedTransaction): ICommand; + // @alpha (undocumented) export function createPactCommandFromTemplate(tpl: IPactCommand): PactCommand; diff --git a/packages/libs/client/src/pact.ts b/packages/libs/client/src/pact.ts index fd057d4985..ea22ed512c 100644 --- a/packages/libs/client/src/pact.ts +++ b/packages/libs/client/src/pact.ts @@ -428,7 +428,10 @@ export class PactCommand // } } -function convertIUnsignedTransactionToICommand( +/** + * @alpha + */ +export function convertIUnsignedTransactionToICommand( transaction: IUnsignedTransaction, ): ICommand { return { diff --git a/packages/libs/client/src/tests/pact.test.ts b/packages/libs/client/src/tests/pact.test.ts index f7a50df7a8..c6349bcab0 100644 --- a/packages/libs/client/src/tests/pact.test.ts +++ b/packages/libs/client/src/tests/pact.test.ts @@ -7,7 +7,11 @@ jest.mock('cross-fetch', () => { import { PactNumber } from '@kadena/pactjs'; import { IUnsignedTransaction } from '../interfaces/IPactCommand'; -import { Pact, PactCommand } from '../pact'; +import { + convertIUnsignedTransactionToICommand, + Pact, + PactCommand, +} from '../pact'; import fetch from 'cross-fetch'; @@ -154,12 +158,16 @@ describe('Pact proxy', () => { const builder = new PactCommand(); builder.code = '(coin.transfer "from" "to" 1.234)'; + builder + .addCap('coin.GAS', 'senderPubKey') + .addSignatures({ pubKey: 'senderPubKey', sig: 'sender-sig' }); + await builder.local('fake-api-host.local.co'); const body = builder.createCommand(); expect(fetch).toBeCalledWith('fake-api-host.local.co/api/v1/local', { - body: JSON.stringify(body), + body: JSON.stringify(convertIUnsignedTransactionToICommand(body)), headers: { 'Content-Type': 'application/json' }, method: 'POST', }); @@ -376,6 +384,8 @@ describe('Pact proxy', () => { }); }); +//TODO: Add timeout test case + describe('TransactionCommand', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const pact = Pact as any; @@ -468,4 +478,35 @@ describe('TransactionCommand', () => { expect(transaction.cmd).not.toEqual(updatedTransaction.cmd); expect(transaction.hash).not.toEqual(updatedTransaction.hash); }); + + it('adds formatted signatures to `sigs` when `addSignatures` is called', async () => { + const transaction = transactionCommand + .addCap('coin.GAS', senderPubKey) + .createCommand(); + + const updatedTransaction = transactionCommand + .addCap('coin.GAS', senderPubKey) + .addSignatures({ + pubKey: senderPubKey, + sig: 'sender-sig', + }) + .createCommand(); + + expect(transaction.sigs).toEqual([undefined]); + expect(updatedTransaction.sigs).toEqual([{ sig: 'sender-sig' }]); + }); + + it('throws error when `addSignatures` is called without signer', async () => { + expect(() => { + transactionCommand = pact.modules.coin['transfer-create']( + sender, + receiver, + () => "(read-keyset 'ks)", + amount, + ).addSignatures({ + pubKey: senderPubKey, + sig: 'sender-sig', + }); + }).toThrow(); + }); });