Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sdk/packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hyperbridge/sdk",
"version": "1.8.5",
"version": "1.8.6",
"description": "The hyperclient SDK provides utilities for querying proofs and statuses for cross-chain requests from HyperBridge.",
"type": "module",
"types": "./dist/node/index.d.ts",
Expand Down
24 changes: 19 additions & 5 deletions sdk/packages/sdk/src/chains/polkadotHub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import type {
} from "@/types"
import { replaceWebsocketWithHttp } from "@/utils"
import { decodeReviveContractTrieId } from "@/utils/reviveAccount"
import { encodeSubstrateEvmProofBytes } from "@/utils/substrate"
import { type CodecType } from "scale-ts"

import { EvmStateProof } from "@/utils/substrate"

/** Substrate default child trie prefix (`ChildInfo::new_default`). */
const DEFAULT_CHILD_STORAGE_PREFIX = new TextEncoder().encode(":child_storage:default:")
Expand Down Expand Up @@ -160,6 +162,7 @@ export class PolkadotHubChain implements IChain {

private async fetchCombinedProof(at: bigint, queries: Map<Uint8Array, Uint8Array[]>): Promise<HexString> {
const height = Number(at)

if (!Number.isSafeInteger(height) || height < 0) {
throw new Error("Block height must be a non-negative safe integer for Substrate RPC")
}
Expand Down Expand Up @@ -206,15 +209,26 @@ export class PolkadotHubChain implements IChain {
blockHash,
])) as ReadProofRpc

const childNodes = childRead.proof.map((p) => hexToBytes(p as HexString))

storageProofEncoded.set(
addr20,
childRead.proof.map((p) => hexToBytes(p as HexString)),
childNodes,
)
}

const encoded = encodeSubstrateEvmProofBytes({
mainProof: mainProofBytes,
storageProof: storageProofEncoded,
// Match `EvmChain.queryProof`: scale-ts `Vector` encoders expect plain arrays of numbers for `Vec<u8>`,
// not `Uint8Array` instances (nested Uint8Arrays can encode incorrectly).
const storageEntries = Array.from(storageProofEncoded.entries())
const contractProofForEnc = mainProofBytes.map((b) => Array.from(b))
const storageProofForEnc = storageEntries.map(([k, nodes]) => [
Array.from(k),
nodes.map((n) => Array.from(n)),
]) as CodecType<typeof EvmStateProof>["storageProof"]

const encoded = EvmStateProof.enc({
contractProof: contractProofForEnc,
storageProof: storageProofForEnc,
})
return bytesToHex(encoded) as HexString
}
Expand Down
24 changes: 2 additions & 22 deletions sdk/packages/sdk/src/utils/substrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ export const H256 = Vector(u8, 32)

export const EvmStateProof = Struct({
/**
* Proof of the contract state.
* Proof of the contract state (EVM account trie) or, for Revive / Substrate EVM, the main state trie proof
* (`AccountInfo` + child root) — same SCALE shape as `SubstrateEvmProof::main_proof` on the Rust side.
*/
contractProof: Vector(Vector(u8)),
/**
Expand All @@ -35,27 +36,6 @@ export const EvmStateProof = Struct({
storageProof: Vector(Tuple(Vector(u8), Vector(Vector(u8)))),
})

/**
* Main trie proof (AccountInfo + child root) plus per-contract child trie proofs for Revive / EVM-on-Substrate.
* Matches `SubstrateEvmProof` in `modules/ismp/state-machines/evm/src/types.rs` (`storage_proof` is a
* `BTreeMap<Vec<u8>, Vec<Vec<u8>>>` — same layout as a length-prefixed list of `(key, value)` pairs).
*/
export const SubstrateEvmProof = Struct({
main_proof: Vector(Vector(u8)),
storage_proof: Vector(Tuple(Vector(u8), Vector(Vector(u8)))),
})

/** Encode proof for Polkadot Hub / Revive; `scale-ts` types `Vector(u8)` as `number[]` but `Uint8Array` is valid at runtime. */
export function encodeSubstrateEvmProofBytes(params: {
mainProof: Uint8Array[]
storageProof: Map<Uint8Array, Uint8Array[]>
}): Uint8Array {
return SubstrateEvmProof.enc({
main_proof: params.mainProof,
storage_proof: Array.from(params.storageProof.entries()),
} as unknown as CodecType<typeof SubstrateEvmProof>)
}

export const SubstrateHashing = Enum({
/* For chains that use keccak as their hashing algo */
Keccak: _void,
Expand Down
Loading