Skip to content

Commit

Permalink
feat: unshielding working
Browse files Browse the repository at this point in the history
  • Loading branch information
mateuszjasiuk committed Jan 9, 2025
1 parent e44cf83 commit 694ba67
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 39 deletions.
50 changes: 38 additions & 12 deletions apps/extension/src/Approvals/ConfirmSignLedgerTx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import clsx from "clsx";
import { ReactNode, useCallback, useEffect, useState } from "react";

import { ActionButton, Stack } from "@namada/components";
import { Ledger, makeBip44Path } from "@namada/sdk/web";
import { Ledger, makeBip44Path, makeSaplingPath } from "@namada/sdk/web";
import { LedgerError, ResponseSign } from "@zondax/ledger-namada";

import { fromBase64 } from "@cosmjs/encoding";
import { fromBase64, toBase64 } from "@cosmjs/encoding";
import { chains } from "@namada/chains";
import { PageHeader } from "App/Common";
import { ApprovalDetails, Status } from "Approvals/Approvals";
import {
QueryPendingTxBytesMsg,
ReplaceMaspSignatureMsg,
SubmitApprovedSignLedgerTxMsg,
} from "background/approvals";
import { QueryAccountDetailsMsg } from "background/keyring";
Expand Down Expand Up @@ -75,15 +76,27 @@ export const ConfirmSignLedgerTx: React.FC<Props> = ({ details }) => {
const signMaspTx = async (
ledger: Ledger,
bytes: Uint8Array,
_path: string
path: string
): Promise<{ sbar: Uint8Array; rbar: Uint8Array }> => {
const _response = await ledger.namadaApp.signMaspSpends(
// TODO:
"m/32'/877'/0'",
const signMaspSpendsResponse = await ledger.namadaApp.signMaspSpends(
path,
Buffer.from(bytes)
);
// TODO
return await ledger.namadaApp.getSpendSignature();

if (signMaspSpendsResponse.returnCode !== LedgerError.NoErrors) {
throw new Error(
`Signing masp spends error encountered: ${signMaspSpendsResponse.errorMessage}`
);
}

const spendSignatureResponse = await ledger.namadaApp.getSpendSignature();
if (spendSignatureResponse.returnCode !== LedgerError.NoErrors) {
throw new Error(
`Getting spends signature error encountered: ${signMaspSpendsResponse.errorMessage}`
);
}

return spendSignatureResponse;
};

const signLedgerTx = async (
Expand Down Expand Up @@ -150,6 +163,9 @@ export const ConfirmSignLedgerTx: React.FC<Props> = ({ details }) => {
index: accountDetails.path.index || 0,
};
const bip44Path = makeBip44Path(chains.namada.bip44.coinType, path);
const zip32Path = makeSaplingPath(chains.namada.bip44.coinType, {
account: path.account,
});
const pendingTxs = await requester.sendMessage(
Ports.Background,
new QueryPendingTxBytesMsg(msgId)
Expand All @@ -162,7 +178,7 @@ export const ConfirmSignLedgerTx: React.FC<Props> = ({ details }) => {
}

const signatures: ResponseSign[] = [];
const maspSignatures: number[][] = [];
const maspSignatures: string[] = [];

let txIndex = 0;
const txCount = pendingTxs.length;
Expand All @@ -182,13 +198,23 @@ export const ConfirmSignLedgerTx: React.FC<Props> = ({ details }) => {
</p>
);
}
const asd = await signMaspTx(ledger, fromBase64(tx), bip44Path);
const maspSignature = [...asd.rbar, ...asd.sbar];
const { sbar, rbar } = await signMaspTx(
ledger,
fromBase64(tx),
zip32Path
);
const maspSignature = toBase64(new Uint8Array([...rbar, ...sbar]));
maspSignatures.push(maspSignature);

const txWithMaspSection = await requester.sendMessage(
Ports.Background,
new ReplaceMaspSignatureMsg(msgId, maspSignature, txIndex)
);
console.log("txWithMaspSection", txWithMaspSection);

const signature = await signLedgerTx(
ledger,
fromBase64(tx),
fromBase64(txWithMaspSection),
bip44Path
);
signatures.push(signature);
Expand Down
14 changes: 14 additions & 0 deletions apps/extension/src/background/approvals/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
QueryTxDetailsMsg,
RejectSignArbitraryMsg,
RejectSignTxMsg,
ReplaceMaspSignatureMsg,
RevokeConnectionMsg,
SubmitApprovedSignArbitraryMsg,
SubmitApprovedSignLedgerTxMsg,
Expand Down Expand Up @@ -113,6 +114,11 @@ export const getHandler: (service: ApprovalsService) => Handler = (service) => {
env,
msg as SubmitApprovedSignLedgerTxMsg
);
case ReplaceMaspSignatureMsg:
return handleReplaceMaspSignatureMsg(service)(
env,
msg as ReplaceMaspSignatureMsg
);

default:
throw new Error("Unknown msg type");
Expand Down Expand Up @@ -287,6 +293,14 @@ const handleSubmitApprovedSignLedgerTxMsg: (
};
};

const handleReplaceMaspSignatureMsg: (
service: ApprovalsService
) => InternalHandler<ReplaceMaspSignatureMsg> = (service) => {
return async (_, { msgId, signature, txIndex }) => {
return await service.replaceMaspSignature(msgId, signature, txIndex);
};
};

const handleCheckIsApprovedSite: (
service: ApprovalsService
) => InternalHandler<CheckIsApprovedSiteMsg> = (service) => {
Expand Down
2 changes: 2 additions & 0 deletions apps/extension/src/background/approvals/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
QueryTxDetailsMsg,
RejectSignArbitraryMsg,
RejectSignTxMsg,
ReplaceMaspSignatureMsg,
RevokeConnectionMsg,
SubmitApprovedSignArbitraryMsg,
SubmitApprovedSignLedgerTxMsg,
Expand All @@ -36,6 +37,7 @@ export function init(router: Router, service: ApprovalsService): void {
router.registerMessage(SubmitApprovedSignTxMsg);
router.registerMessage(SubmitApprovedSignArbitraryMsg);
router.registerMessage(SubmitApprovedSignLedgerTxMsg);
router.registerMessage(ReplaceMaspSignatureMsg);
router.registerMessage(IsConnectionApprovedMsg);
router.registerMessage(ApproveConnectInterfaceMsg);
router.registerMessage(ConnectInterfaceResponseMsg);
Expand Down
33 changes: 32 additions & 1 deletion apps/extension/src/background/approvals/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export enum MessageType {
SubmitApprovedSignTx = "submit-approved-sign-tx",
SubmitApprovedSignArbitrary = "submit-approved-sign-arbitrary",
SubmitApprovedSignLedgerTx = "submit-approved-sign-ledger-tx",
ReplaceMaspSignature = "replace-masp-signature",
RejectSignArbitrary = "reject-sign-arbitrary",
ConnectInterfaceResponse = "connect-interface-response",
DisconnectInterfaceResponse = "disconnect-interface-response",
Expand Down Expand Up @@ -54,7 +55,8 @@ export class SubmitApprovedSignLedgerTxMsg extends Message<void> {
constructor(
public readonly msgId: string,
public readonly responseSign: ResponseSign[],
public readonly maspSignatures: number[][]
//base64 encoded masp signatures
public readonly maspSignatures: string[]
) {
super();
}
Expand All @@ -72,6 +74,35 @@ export class SubmitApprovedSignLedgerTxMsg extends Message<void> {
}
}

// returns base64 encoded tx
export class ReplaceMaspSignatureMsg extends Message<string> {
public static type(): MessageType {
return MessageType.ReplaceMaspSignature;
}

constructor(
public readonly msgId: string,
// base64 encoded
public readonly signature: string,
// pending tx index
public readonly txIndex: number
) {
super();
}

validate(): void {
validateProps(this, ["msgId", "signature", "txIndex"]);
}

route(): string {
return ROUTE;
}

type(): string {
return ReplaceMaspSignatureMsg.type();
}
}

export class RejectSignTxMsg extends Message<void> {
public static type(): MessageType {
return MessageType.RejectSignTx;
Expand Down
52 changes: 40 additions & 12 deletions apps/extension/src/background/approvals/service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { toBase64 } from "@cosmjs/encoding";
import { fromBase64, toBase64 } from "@cosmjs/encoding";
import { v4 as uuid } from "uuid";
import browser, { Windows } from "webextension-polyfill";

Expand Down Expand Up @@ -137,7 +137,7 @@ export class ApprovalsService {
popupTabId: number,
msgId: string,
responseSign: ResponseSign[],
maspSignatures: number[][]
maspSignatures: string[]
): Promise<void> {
const pendingTx = await this.txStore.get(msgId);
const resolvers = this.getResolver(popupTabId);
Expand All @@ -152,19 +152,22 @@ export class ApprovalsService {

const { tx } = this.sdkService.getSdk();

console.log("maspSignatures", maspSignatures);
try {
const signedTxs = pendingTx.txs.map(({ bytes, signingData }, i) => {
const sd = signingData.map((sd) =>
new Message().encode(new SigningDataMsgValue(sd))
const signedTxs = pendingTx.txs.map((pendingTx, i) => {
const signingData = pendingTx.signingData.map((signingData) =>
new Message().encode(new SigningDataMsgValue(signingData))
);
const maspSignature = fromBase64(maspSignatures[i]);
// TODO: consider improving this, explanation below:
// Because we read tx from the store we have to append masp signatures twice
// First time before ledger computes tx wrapper signature and second time now to submit proper tx
const txWithMasp = tx.appendMaspSignature(
pendingTx.bytes,
signingData,
maspSignature
);
const wwww = new Uint8Array(maspSignatures[i]);

console.log("sd", sd, maspSignatures[i], i);
const asd = tx.appendMaspSignature(bytes, sd, wwww);
console.log("asd", asd);
// return tx.appendSignature(asd, responseSign[i]);
return asd;
return tx.appendSignature(txWithMasp, responseSign[i]);
});
resolvers.resolve(signedTxs);
} catch (e) {
Expand All @@ -174,6 +177,31 @@ export class ApprovalsService {
await this.clearPendingSignature(msgId);
}

async replaceMaspSignature(
msgId: string,
signature: string,
txIndex: number
): Promise<string> {
const pendingTx = (await this.txStore.get(msgId))?.txs.at(txIndex);

if (!pendingTx) {
throw new Error(ApprovalErrors.TransactionDataNotFound(msgId));
}

const { tx } = this.sdkService.getSdk();

const signingData = pendingTx.signingData.map((signingData) =>
new Message().encode(new SigningDataMsgValue(signingData))
);
const txWithMasp = tx.appendMaspSignature(
pendingTx.bytes,
signingData,
fromBase64(signature)
);

return toBase64(txWithMasp);
}

async submitSignArbitrary(
popupTabId: number,
msgId: string,
Expand Down
2 changes: 1 addition & 1 deletion apps/namadillo/public/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
#indexer_url = ""
#rpc_url = ""
#masp_indexer_url = ""
#localnet_enabled = false
localnet_enabled = true
13 changes: 11 additions & 2 deletions apps/namadillo/src/atoms/transfer/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,22 +188,31 @@ export const createUnshieldingTransferTx = async (
const token = props[0]?.data[0]?.token;
const amount = props[0]?.data[0]?.amount;

const sdk = await getSdkInstance();
const ledger = await sdk.initLedger();

const bparams = await ledger.getBparams();
ledger.closeTransport();
console.log("bparams closed", bparams);

return await workerBuildTxPair({
rpcUrl,
token,
signerAddress: disposableSigner.address,
signerAddress: account.address,
// signerAddress: disposableSigner.address,
buildTxFn: async (workerLink) => {
const msgValue = new UnshieldingTransferMsgValue({
source,
gasSpendingKey: source,
data: [{ target: destination, token, amount }],
bparams,
});
const msg: Unshield = {
type: "unshield",
payload: {
account: {
...account,
publicKey: disposableSigner.publicKey,
// publicKey: disposableSigner.publicKey,
},
gasConfig,
props: [msgValue],
Expand Down
2 changes: 1 addition & 1 deletion apps/namadillo/src/workers/MaspTxWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ async function unshield(

await sdk.masp.loadMaspParams("", chain.chainId);

console.log("Unshielding props", unshieldingProps);
const encodedTxData = await buildTx<UnshieldingTransferMsgValue>(
sdk,
account,
Expand All @@ -125,6 +124,7 @@ async function unshield(
sdk.tx.buildUnshieldingTransfer,
true
);
console.log("encodedTxData", encodedTxData);

return encodedTxData;
}
Expand Down
26 changes: 16 additions & 10 deletions packages/shared/lib/src/sdk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,22 +596,28 @@ impl Sdk {
(tx, masp_signing_data)
}
BuildParams::StoredBuildParams(mut bparams) => {
web_sys::console::log_1(&"StoredBuildParams".into());
let tx = build_unshielding_transfer(&self.namada, &mut args, &mut bparams).await?;
let masp_signing_data = MaspSigningData::new(bparams, xfvks);

(tx, masp_signing_data)
}
};

if let Some(shielded_hash) = signing_data.shielded_hash {
web_sys::console::log_1(
&format!(
"tx: {:?}",
borsh::to_vec(tx.get_masp_section(&shielded_hash).unwrap())
)
.into(),
);
}
web_sys::console::log_1(&format!("signing_data owner: {:?}", signing_data.owner).into());
web_sys::console::log_1(
&format!("signing_data public_keys: {:?}", signing_data.public_keys).into(),
);
web_sys::console::log_1(&format!("signing_data fee: {:?}", signing_data.fee_payer).into());

// if let Some(shielded_hash) = signing_data.shielded_hash {
// web_sys::console::log_1(
// &format!(
// "tx: {:?}",
// borsh::to_vec(tx.get_masp_section(&shielded_hash).unwrap())
// )
// .into(),
// );
// }

self.serialize_tx_result(tx, wrapper_tx_msg, signing_data, Some(masp_signing_data))
}
Expand Down

0 comments on commit 694ba67

Please sign in to comment.