0xMiden / 0xMiden/wallet-adapter

Sending a note bricks the wallet if NoteMetadata sender is not the wallet account itself

未关闭
#89 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
TypeScript
星标
2
派生
9
平均合并
25 分钟
30 天内合并 PR
1

描述

### Packages versions

"@miden-sdk/miden-sdk": "0.14.10",
"@miden-sdk/miden-wallet-adapter": "0.14.3",
"@miden-sdk/react": "0.14.10",

### Bug description

Sending a note bricks the wallet if NoteMetadata sender is not the wallet account itself.

For example on p2ide like this:

```tsx
const noteBuilt = createP2IDENote({
from: notWalletAccountId,
to: whomeverAccountId,
assets: { token: fungibleFaucetId, amount: fungibleAmount },
type: NoteVisibility.Public,
reclaimAfter: P2IDE_RECLAIM_AFTER,
timelockUntil: P2IDE_TIMELOCK_UNTIL,
});
```

Closing / restarting browser does not help. Only reinstalling the wallet helps recover the account.

### How can this be reproduced?

Run the below example or run/take the code from here: https://github.com/0x0-mico/miden_consumable_notes/blob/another-sender/src/main.tsx

It will create a P2IDE note and try to send it to the network
Observe that this will brick the wallet:

It will be executing forever:
Image

And wallet will "lose connection" to the node
Image

```tsx
import {
AccountId,
createP2IDENote,
Note,
NoteArray,
NoteVisibility,
TransactionRequestBuilder,
} from '@miden-sdk/miden-sdk';
import {
ConsumeTransaction,
CustomTransaction,
MidenWalletAdapter,
MidenWalletName,
PrivateDataPermission,
Transaction,
TransactionType,
useWallet,
WalletAdapterNetwork,
WalletModalProvider,
WalletMultiButton,
WalletProvider,
} from '@miden-sdk/miden-wallet-adapter';
import '@miden-sdk/miden-wallet-adapter/styles.css';
import { MidenProvider, useMiden } from '@miden-sdk/react';
import { useEffect, useState } from 'react';
import { createRoot } from 'react-dom/client';

const midenWalletAdapters = [new MidenWalletAdapter({ appName: 'position-consume' })];
const poolAccountId = AccountId.fromBech32('mtst1azplz9r5fyw36grz8s92cenuns80075k');

/** Reclaim enabled (non-zero); timelock 0 = unlocked at any block height. */
const P2IDE_RECLAIM_AFTER = 1;
const P2IDE_TIMELOCK_UNTIL = 0;

function App() {
const { isReady } = useMiden();
const { connected, address, select, requestTransaction, requestAssets, requestConsume } = useWallet();
const [p2ideNote, setP2ideNote] = useState(null);
const [message, setMessage] = useState('');

useEffect(() => {
select(MidenWalletName);
}, [select]);

async function p2ideMain(step: 'open' | 'reclaim') {
if (!isReady || !connected || !address || !requestTransaction) {
setMessage('connect wallet first');
return;
}
try {
setMessage('');
if (step === 'open') {
if (!requestAssets) return;
const walletAssets = await requestAssets();
const firstWalletAsset = walletAssets[0];
if (!firstWalletAsset) {
setMessage('wallet has no assets');
return;
}
const fungibleFaucetId = AccountId.fromBech32(firstWalletAsset.faucetId);
const fungibleAmount = BigInt(firstWalletAsset.amount) / BigInt(10);
const noteBuilt = createP2IDENote({
from: poolAccountId,
to: poolAccountId,
assets: { token: fungibleFaucetId, amount: fungibleAmount },
type: NoteVisibility.Public,
reclaimAfter: P2IDE_RECLAIM_AFTER,
timelockUntil: P2IDE_TIMELOCK_UNTIL,
});
console.log("Note created.")
const openRequest = new TransactionRequestBuilder()
.withOwnOutputNotes(new NoteArray([noteBuilt]))
.build();
await requestTransaction(
new Transaction(
TransactionType.Custom,
new CustomTransaction(address, address, openRequest),
),
);
console.log("Note sent.")
setP2ideNote(noteBuilt);
setMessage(`sent P2IDE ${noteBuilt.id()} → pool`);
return;
}
if (!p2ideNote) {
setMessage('send P2IDE note first');
return;
}
const noteAsset = p2ideNote.assets().fungibleAssets()[0];
if (!noteAsset) {
setMessage('note has no fungible asset');
return;
}
await requestConsume?.(
new ConsumeTransaction(
noteAsset.faucetId().toString(),
p2ideNote.id().toString(),
'public',
Number(noteAsset.amount()),
p2ideNote.serialize(),
),
);
setMessage(`reclaimed ${p2ideNote.id()}`);
setP2ideNote(null);
} catch (error) {
setMessage(String(error));
}
}

return (


P2IDE repro — pool target {poolAccountId.toString()}



{connected && address &&

wallet: {address}

}
p2ideMain('open')}>
send P2IDE note

p2ideMain('reclaim')}>
reclaim (ConsumeTransaction)

{p2ideNote &&

note: {p2ideNote.id().toString()}

}
{p2ideNote &&

script root: {p2ideNote.script().root().toHex()}

}
{message &&

{message}

}

);
}

createRoot(document.getElementById('root')!).render(






,
);

```

### Relevant log output

wallet logs out this:

```shell
INDEX.JS: Error in executeTransaction: Error: failed to execute transaction: invalid transaction request: account interface error: invalid sender account: 0x83f11474491d1d20623c0aac667c9c
at __wbg_Error_8c4e43fe74559d73 (Cargo-DKB2aRX-.js:23077:20)
at miden_client_web.wasm.wasm_bindgen[cb32f6f48015412b]::__wbindgen_error_new::__wbg_Error_8c4e43fe74559d73 externref shim (miden_client_web.d-qyt3-n.wasm:0xc1a487)
at miden_client_web.wasm.miden_client_web[8b5bfd558e02b233]::js_error_with_context:: (miden_client_web.d-qyt3-n.wasm:0xa4ee6c)
at miden_client_web.wasm.::execute_transaction::{closure#0} (miden_client_web.d-qyt3-n.wasm:0xaf47df)
at miden_client_web.wasm.wasm_bindgen_futures[203ad115dbfdc77c]::future_to_promise::<::execute_transaction::{closure#0}::_::__wasm_bindgen_generated_WebClient_executeTransaction::{closure#0}>::{closure#0}::{closure#0} (miden_client_web.d-qyt3-n.wasm:0x93423b)
at miden_client_web.wasm.::run (miden_client_web.d-qyt3-n.wasm:0xa8ae5c)
at miden_client_web.wasm.::spawn::::pull::{closure#0}>, ::pull::{closure#1}>>>::{closure#0}::{closure#0}>::{closure#0} (miden_client_web.d-qyt3-n.wasm:0xbb64a8)
at miden_client_web.wasm.wasm_bindgen[cb32f6f48015412b]::convert::closures::_::invoke:: (miden_client_web.d-qyt3-n.wasm:0xc19131)
at miden_client_web.wasm.wasm_bindgen[cb32f6f48015412b]::convert::closures::_::invoke:: externref shim (miden_client_web.d-qyt3-n.wasm:0xc1c4a3)
```

贡献指南

打开贡献指南

调研方向

The bug occurs when NoteMetadata sender differs from the wallet account. Examine the createP2IDENote function and the transaction execution flow in the wallet adapter. Look at the error 'invalid sender account' in the logs. Start by tracing the note creation and validation in the SDK, then check how the wallet adapter handles transaction requests with mismatched senders.

由索引模型根据 Issue 内容生成。

评估

技术栈
nodejs, react, typescript
领域
blockchain
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
描述清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。