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
4 changes: 4 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,8 @@ jobs:

- name: Run tests
working-directory: e2e
env:
# Use fast-runtime binary for staking package, release binary for others
# Path is relative to package directory (e2e/<package>/)
BINARY_PATH: ${{ matrix.package == 'e2e-staking' && '../../target/fast/node-subtensor' || '../../target/release/node-subtensor' }}
run: pnpm --filter ${{ matrix.package }} test
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ scripts/specs/local.json

# Node modules
node_modules

# Claude Code configuration
.claude
88 changes: 65 additions & 23 deletions e2e/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions e2e/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
packages:
- shared
- shield
- staking

catalog:
"@noble/ciphers": "^2.1.1"
Expand Down
44 changes: 44 additions & 0 deletions e2e/shared/address.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { sr25519CreateDerive } from "@polkadot-labs/hdkd";
import { DEV_PHRASE, entropyToMiniSecret, mnemonicToEntropy, KeyPair } from "@polkadot-labs/hdkd-helpers";
import { getPolkadotSigner } from "polkadot-api/signer";
import { PolkadotSigner } from "polkadot-api";
import { randomBytes } from "crypto";
import { ss58Address } from "@polkadot-labs/hdkd-helpers";

export const SS58_PREFIX = 42;

// ─── KEYPAIR UTILITIES ───────────────────────────────────────────────────────

export function getKeypairFromPath(path: string): KeyPair {
const entropy = mnemonicToEntropy(DEV_PHRASE);
const miniSecret = entropyToMiniSecret(entropy);
const derive = sr25519CreateDerive(miniSecret);
return derive(path);
}

export const getAlice = () => getKeypairFromPath("//Alice");

export function getRandomSubstrateKeypair(): KeyPair {
const seed = randomBytes(32);
const miniSecret = entropyToMiniSecret(seed);
const derive = sr25519CreateDerive(miniSecret);
return derive("");
}

// ─── SIGNER UTILITIES ────────────────────────────────────────────────────────

export function getSignerFromKeypair(keypair: KeyPair): PolkadotSigner {
return getPolkadotSigner(keypair.publicKey, "Sr25519", keypair.sign);
}

export function getSignerFromPath(path: string): PolkadotSigner {
return getSignerFromKeypair(getKeypairFromPath(path));
}

export const getAliceSigner = () => getSignerFromPath("//Alice");

// ─── ADDRESS UTILITIES ───────────────────────────────────────────────────────

export function convertPublicKeyToSs58(publicKey: Uint8Array): string {
return ss58Address(publicKey, SS58_PREFIX);
}
29 changes: 29 additions & 0 deletions e2e/shared/balance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { subtensor, MultiAddress } from "@polkadot-api/descriptors";
import { TypedApi } from "polkadot-api";
import { getAliceSigner } from "./address.js";
import { waitForTransactionWithRetry } from "./transactions.js";

export const TAO = BigInt(1000000000); // 10^9 RAO per TAO

export function tao(value: number): bigint {
return TAO * BigInt(value);
}

export async function getBalance(api: TypedApi<typeof subtensor>, ss58Address: string): Promise<bigint> {
const account = await api.query.System.Account.getValue(ss58Address);
return account.data.free;
}

export async function forceSetBalance(
api: TypedApi<typeof subtensor>,
ss58Address: string,
amount: bigint = tao(1e10)
): Promise<void> {
const alice = getAliceSigner();
const internalCall = api.tx.Balances.force_set_balance({
who: MultiAddress.Id(ss58Address),
new_free: amount,
});
const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall });
await waitForTransactionWithRetry(api, tx, alice, "force_set_balance");
}
Loading
Loading