Skip to content

Conversation

@shannonwells
Copy link
Contributor

@shannonwells shannonwells commented Nov 21, 2025

This PR implements one endpoint in the account-api to be called by the MCP server, which will be sending it 3 payloads. It creates an array of 3 encoded calls and enqueues it to a separate HCP queue. The account-worker has a new function for processing the HCP queue, which calls payWithCapacityBatchAll with each set of 3 calls.

I'm not fond of the name ('publishAll') I came up with, happy to hear suggestions

  • Short proposal doc
  • controller (in account-api)
  • HCP enqueuing function in EnqueueService
  • HCP BullMQ in account-worker, verified
  • unit tests
  • e2e tests
  • generate swagger docs

@shannonwells shannonwells changed the title Feat/hcp proposal doc HCP publishing endpoint for first time account creation Nov 26, 2025
@shannonwells shannonwells marked this pull request as ready for review January 8, 2026 20:14
@shannonwells shannonwells requested a review from a team January 8, 2026 20:14
@shannonwells shannonwells marked this pull request as draft January 8, 2026 23:00
Comment on lines +49 to +29
const mockApiPromise = {
...EventEmitter2.prototype,
isReady: Promise.resolve(),
tx: {
statefulStorage: {
applyItemActionsWithSignatureV2: jest.fn().mockImplementation(() => mockSubmittableExtrinsic('0x01020304')),
upsertPageWithSignatureV2: jest.fn().mockImplementation(() => mockSubmittableExtrinsic('0x05060708')),
},
},
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: In order to keep mocks in a single place, and build up a complete chain mock over time, there's mockApiPromise in testlib/polkadot-api.mock.spec.ts. The pattern has been:

  1. Add the mocked functions with an empty jest.fn() as the implementation
  2. Override with a specific mock implementation in your test; this can be done in the top beforeAll(...) or in any specific test.

ie, in testlib/polkadot-api.mock.spec.ts, add to the tx property:

statefulStorage: {
  applyItemActionsWithSignatureV2: jest.fn(),
  upsertPageWithSignatureV2: jest.fn(),
}

Then in your test suite, just:

jest.spyOn(mockApiPromise.tx.statefulStorage, 'applyItemActionsWithSignatureV2').mockResolvedValue(mockSubmittableExtrinsic('0x01020304'));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: The pattern may not always have been followed, but we can try... my opinion, FWIW:
controllers should have little to no business logic. They just marshall the request/response; business logic is in a service component. This makes it easy to propagate endpoints to new controllers/API versions without having to duplicate business logic.

This also means that unit tests can focus on the service components, while controllers get tested primarily with a live HTTP request/response in an E2E test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had intended to make a service for this and backed out because it seemed like it was not enough code to be worth it. But I buy your separation of concerns argument.

await this.cacheTransactionStatus(payWithCapacityTxHash, status);
} catch (error: unknown) {
if (error instanceof DelayedError) {
job.moveToDelayed(Date.now(), job.token);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: worth noting here that this is a "fake" delay simply to put this job back on the queue--under proper circumstances, since we've now detected we're out of Capacity, an event should have been emitted that paused the queue until the next epoch, which prevents us from just spinning on transactions while we're out of Capacity.

@@ -1,10 +1,16 @@
#!/bin/bash

function exit_err() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was tired of this script continuing even when e.g. Docker daemon wasn't running.

shannonwells and others added 29 commits January 13, 2026 18:17
* spellchecking update: add to dictionary, make it quiet
Exit startup script on error
Regen package-lock.json
- fix reference
- controller tests passing
- e2e tests running properly
Co-authored-by: Joe Caputo <joseph.caputo@projectliberty.io>
Co-authored-by: Joe Caputo <joseph.caputo@projectliberty.io>
- remove some console logs
- linting
@shannonwells shannonwells force-pushed the feat/hcp-proposal-doc branch from ac7fcc0 to 7d9085b Compare January 14, 2026 02:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants