Skip to content
Closed
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
8 changes: 4 additions & 4 deletions pallets/dispenser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,8 @@ pub mod pallet {
)?;

// Construct signing path used by SigNet.
let mut path = Vec::with_capacity(2 + requester.encoded_size() * 2);
path.extend_from_slice(b"0x");
path.extend_from_slice(hex::encode(requester.encode()).as_bytes());
// Fixed path so all requests derive the same MPC key (single funded address).
let path = b"dispenser".to_vec();

// CAIP-2 chain ID (e.g., "eip155:1" for Ethereum mainnet)
let caip2_id = alloc::format!("eip155:{}", tx.chain_id);
Expand Down Expand Up @@ -331,7 +330,8 @@ pub mod pallet {
Preservation::Expendable,
)?;

let output_deserialization_schema = Vec::<u8>::new();
let output_deserialization_schema =
serde_json::to_vec(&serde_json::json!([])).map_err(|_| Error::<T>::Serialization)?;
let respond_serialization_schema =
serde_json::to_vec(&serde_json::json!("bool")).map_err(|_| Error::<T>::Serialization)?;

Expand Down
13 changes: 8 additions & 5 deletions scripts/dispenser-tests/dispenser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe('ERC20 Vault Integration', () => {
let derivedPubKey: string
let aliceHexPath: string
let palletSS58: string
let onChainFaucetAddress: string

beforeAll(async () => {
await waitReady()
Expand All @@ -40,10 +41,12 @@ describe('ERC20 Vault Integration', () => {
const feeAsset = (api.consts.ethDispenser.feeAsset as any).toNumber()
const faucetAsset = (api.consts.ethDispenser.faucetAsset as any).toNumber()

onChainFaucetAddress = (api.consts.ethDispenser.faucetAddress as any).toHex()

console.log(
`feeAsset = ${feeAsset}`,
`faucetAsset = ${faucetAsset}`,
`faucetAddress = ${api.consts.ethDispenser.faucetAddress.toString()}`,
`faucetAddress = ${onChainFaucetAddress}`,
)

const { keyring, alice: aliceAcc, bob } = createKeyringAndAccounts()
Expand All @@ -53,7 +56,7 @@ describe('ERC20 Vault Integration', () => {
aliceHexPath = '0x' + u8aToHex(aliceAccountId).slice(2)

await logAliceTokenBalances(api, alice, faucetAsset, feeAsset)
await ensureBobHasAssets(api, bob, faucetAsset)
await ensureBobHasAssets(api, alice, bob, faucetAsset)

const palletFunding = await fundPalletAccounts(api, alice, faucetAsset)
palletSS58 = palletFunding.palletSS58
Expand All @@ -67,7 +70,7 @@ describe('ERC20 Vault Integration', () => {
ENV.SUBSTRATE_CHAIN_ID,
)

const derived = deriveEthAddress()
const derived = deriveEthAddress(palletSS58)
derivedEthAddress = derived.derivedEthAddress
derivedPubKey = derived.derivedPubKey

Expand Down Expand Up @@ -118,7 +121,7 @@ describe('ERC20 Vault Integration', () => {
maxPriorityFeePerGas: txParams.maxPriorityFeePerGas,
maxFeePerGas: txParams.maxFeePerGas,
gasLimit: txParams.gasLimit,
to: ENV.FAUCET_ADDRESS,
to: onChainFaucetAddress,
value: 0,
data,
})
Expand All @@ -129,7 +132,7 @@ describe('ERC20 Vault Integration', () => {
{
caip2_id: `eip155:${ENV.EVM_CHAIN_ID}`,
keyVersion: 0,
path: aliceHexPath,
path: 'dispenser',
algo: 'ecdsa',
dest: 'ethereum',
params: '',
Expand Down
4 changes: 3 additions & 1 deletion scripts/dispenser-tests/key-derivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ export class KeyDerivation {

static derivePublicKey(
rootPublicKey: string,
predecessorId: string,
path: string,
chainId: string
): string {
const ec = new EC("secp256k1");

const uncompressedRoot = rootPublicKey.slice(4);

const derivationPath = `${this.EPSILON_PREFIX},${chainId}`;
const derivationPath = `${this.EPSILON_PREFIX},${chainId},${predecessorId},${path}`;
const hash = ethers.keccak256(ethers.toUtf8Bytes(derivationPath));
const scalarHex = hash.slice(2);

Expand Down
33 changes: 19 additions & 14 deletions scripts/dispenser-tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ export function createKeyringAndAccounts() {

export async function ensureBobHasAssets(
api: ApiPromise,
alice: any,
bob: any,
faucetAsset: number,
) {
Expand All @@ -240,21 +241,23 @@ export async function ensureBobHasAssets(
bob.address,
)) as any

const bobFaucetBalance = await getTokenFree(api, bob.address, faucetAsset)

if (bobBalance.free.toBigInt() < MIN_BOB_NATIVE_BALANCE) {
throw new Error(
`Bob has insufficient native balance: ${bobBalance.free.toBigInt()}. ` +
`Expected at least ${MIN_BOB_NATIVE_BALANCE}. Fund Bob via chopsticks config.`,
)
if (bobBalance.free.toBigInt() < 1000000000000n) {
console.log('Funding Bob from Alice...')
await new Promise<void>((resolve, reject) => {
api.tx.balances
.transferKeepAlive(bob.address, 100000000000000n)
.signAndSend(alice, (result: ISubmittableResult) => {
if (result.dispatchError) {
reject(result.dispatchError)
} else if (result.status.isInBlock) {
console.log("Bob's account funded!")
resolve()
}
})
})
}

if (bobFaucetBalance < ethers.parseEther('1')) {
throw new Error(
`Bob has insufficient faucet asset (${faucetAsset}) balance: ${bobFaucetBalance}. ` +
`Fund Bob via chopsticks config.`,
)
}
const bobFaucetBalance = await getTokenFree(api, bob.address, faucetAsset)

console.log(
`Bob balances: native=${bobBalance.free.toBigInt()}, faucetAsset(${faucetAsset})=${bobFaucetBalance}`,
Expand Down Expand Up @@ -318,12 +321,14 @@ export async function fundPalletAccounts(
return { palletSS58 }
}

export function deriveEthAddress(): {
export function deriveEthAddress(palletSS58: string): {
derivedPubKey: string
derivedEthAddress: string
} {
const derivedPubKey = KeyDerivation.derivePublicKey(
ENV.ROOT_PUBLIC_KEY,
palletSS58,
'dispenser',
ENV.SUBSTRATE_CHAIN_ID,
)

Expand Down
Loading