Implement message id extraction for Cosmos (#3380)

### Description

- Implement message id extraction for `CosmWasmCoreAdapter`
- Add `extractMessageIds` method to `MultiProtocolCore`

### Related issues

https://github.com/hyperlane-xyz/issues/issues/927

### Backward compatibility

Yes

### Testing

Added unit tests
pull/3382/head
J M Rossy 9 months ago committed by GitHub
parent 9abdf7c832
commit c2bf423add
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      .changeset/tasty-eyes-grin.md
  2. 9
      typescript/sdk/src/core/MultiProtocolCore.ts
  3. 36
      typescript/sdk/src/core/adapters/CosmWasmCoreAdapter.test.ts
  4. 35
      typescript/sdk/src/core/adapters/CosmWasmCoreAdapter.ts
  5. 1
      typescript/sdk/src/core/adapters/SealevelCoreAdapter.ts
  6. 1
      typescript/sdk/src/index.ts

@ -0,0 +1,5 @@
---
'@hyperlane-xyz/sdk': patch
---
Implement message id extraction for CosmWasmCoreAdapter

@ -1,6 +1,6 @@
import debug from 'debug';
import { ProtocolType } from '@hyperlane-xyz/utils';
import { HexString, ProtocolType } from '@hyperlane-xyz/utils';
import { AdapterClassType, MultiProtocolApp } from '../app/MultiProtocolApp';
import {
@ -59,6 +59,13 @@ export class MultiProtocolCore extends MultiProtocolApp<
throw new Error(`No adapter for protocol ${protocol}`);
}
extractMessageIds(
origin: ChainName,
sourceTx: TypedTransactionReceipt,
): Array<{ messageId: HexString; destination: ChainName }> {
return this.adapter(origin).extractMessageIds(sourceTx);
}
async waitForMessagesProcessed(
origin: ChainName,
destination: ChainName,

File diff suppressed because one or more lines are too long

@ -1,6 +1,6 @@
import { ExecuteInstruction } from '@cosmjs/cosmwasm-stargate';
import { Address, HexString } from '@hyperlane-xyz/utils';
import { Address, HexString, assert, ensure0x } from '@hyperlane-xyz/utils';
import { BaseCosmWasmAdapter } from '../../app/MultiProtocolApp';
import {
@ -24,6 +24,11 @@ import { ChainName } from '../../types';
import { ICoreAdapter } from './types';
const MESSAGE_DISPATCH_EVENT_TYPE = 'wasm-mailbox_dispatch';
const MESSAGE_DISPATCH_ID_EVENT_TYPE = 'wasm-mailbox_dispatch_id';
const MESSAGE_ID_ATTRIBUTE_KEY = 'message_id';
const MESSAGE_DESTINATION_ATTRIBUTE_KEY = 'destination';
type MailboxResponse =
| DefaultHookResponse
| RequiredHookResponse
@ -169,8 +174,32 @@ export class CosmWasmCoreAdapter
`Unsupported provider type for CosmosCoreAdapter ${sourceTx.type}`,
);
}
// TODO: parse mailbox logs and extract message ids
throw new Error('Method not implemented.');
const dispatchIdEvents = sourceTx.receipt.events.filter(
(e) => e.type === MESSAGE_DISPATCH_ID_EVENT_TYPE,
);
const dispatchEvents = sourceTx.receipt.events.filter(
(e) => e.type === MESSAGE_DISPATCH_EVENT_TYPE,
);
assert(
dispatchIdEvents.length === dispatchEvents.length,
'Mismatched dispatch and dispatch id events',
);
const result: Array<{ messageId: string; destination: ChainName }> = [];
for (let i = 0; i < dispatchIdEvents.length; i++) {
const idAttribute = dispatchIdEvents[i].attributes.find(
(a) => a.key === MESSAGE_ID_ATTRIBUTE_KEY,
);
const destAttribute = dispatchEvents[i].attributes.find(
(a) => a.key === MESSAGE_DESTINATION_ATTRIBUTE_KEY,
);
assert(idAttribute, 'No message id attribute found in dispatch event');
assert(destAttribute, 'No destination attribute found in dispatch event');
result.push({
messageId: ensure0x(idAttribute.value),
destination: this.multiProvider.getChainName(destAttribute.value),
});
}
return result;
}
async waitForMessageProcessed(

@ -45,7 +45,6 @@ export class SealevelCoreAdapter
if (!logs)
throw new Error('Transaction logs required to check message delivery');
const parsedLogs = SealevelCoreAdapter.parseMessageDispatchLogs(logs);
if (!parsedLogs.length) throw new Error('Message dispatch log not found');
return parsedLogs.map(({ destination, messageId }) => ({
messageId: ensure0x(messageId),
destination: this.multiProvider.getChainName(destination),

@ -63,6 +63,7 @@ export {
TestRecipientConfig,
TestRecipientDeployer,
} from './core/TestRecipientDeployer';
export { CosmWasmCoreAdapter } from './core/adapters/CosmWasmCoreAdapter';
export { EvmCoreAdapter } from './core/adapters/EvmCoreAdapter';
export { SealevelCoreAdapter } from './core/adapters/SealevelCoreAdapter';
export { ICoreAdapter } from './core/adapters/types';

Loading…
Cancel
Save