Skip to content

Commit

Permalink
fix: the beacon wallet sign is now working
Browse files Browse the repository at this point in the history
  • Loading branch information
ac10n committed Aug 3, 2023
1 parent d221ceb commit 525afd7
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 34 deletions.
2 changes: 1 addition & 1 deletion apps/taquito-test-dapp/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "taquito-test-dapp-vite",
"name": "taquito-test-dapp",
"private": true,
"version": "17.1.1",
"type": "module",
Expand Down
1 change: 1 addition & 0 deletions apps/taquito-test-dapp/src/lib/TestContainer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
if (
test.id === "sign-payload" ||
test.id === "sign-payload-and-send" ||
test.id === "sign-failingNoop" ||
test.id === "verify-signature" ||
test.id === "set-transaction-limits"
) {
Expand Down
37 changes: 37 additions & 0 deletions apps/taquito-test-dapp/src/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,30 @@ const signPayloadAndSend = async (
}
};

const signFailingNoop = async (
input: string,
tezos: TezosToolkit,
wallet: BeaconWallet,
): Promise<TestResult> => {
const bytes = char2Bytes(input);
try {
const signedPayload = await tezos.wallet.signFailingNoop({
arbitrary: bytes,
basedOnBlock: 'head'
});

return {
success: true,
opHash: "",
output: signedPayload.prefixSig,
sigDetails: { input, bytes: signedPayload.bytes, formattedInput: input }
};
} catch (error) {
console.log(error);
return { success: false, opHash: "", output: JSON.stringify(error) };
}
};

const verifySignatureWithTaquito = async (
input: string,
wallet: BeaconWallet,
Expand Down Expand Up @@ -535,6 +559,7 @@ export const list = [
"Use the Batch API for contract calls",
"Sign the provided payload",
"Sign and send the signature to the contract",
"Sign the provided payload in a failing noop",
"Verify a provided signature",
"Set the transaction limits",
"Subscribe to confirmations",
Expand Down Expand Up @@ -678,6 +703,18 @@ export const init = (
inputType: "string",
lastResult: { option: "none", val: false }
},
{
id: "sign-failingNoop",
name: "Sign the provided payload in a failing noop",
description: "This test signs the payload provided by the user wrapped in a failing noop",
documentation: 'https://tezostaquito.io/docs/signing/#generating-a-signature-with-beacon-sdk',
keyword: 'failingNoop',
run: input => signFailingNoop(input.text, Tezos, wallet),
showExecutionTime: false,
inputRequired: true,
inputType: "string",
lastResult: { option: "none", val: false }
},
{
id: "verify-signature",
name: "Verify a provided signature",
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

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

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
"integration-tests"
],
"scripts": {
"build": "nx run-many --target=build --exclude=@taquito/website,taquito-test-dapp-vite",
"build-test-dapp": "lerna run build --scope=taquito-test-dapp-vite",
"build": "nx run-many --target=build --exclude=@taquito/website,taquito-test-dapp",
"build-all": "nx run-many --target=build --exclude=@taquito/website",
"build-test-dapp": "lerna run build --scope=taquito-test-dapp",
"rebuild": "npm run clean && npm clean-install && npm run build",
"test": "nx run-many --target=test --exclude=integration-tests,@taquito/website,taquito-test-dapp-vite --collectCoverage",
"test": "nx run-many --target=test --exclude=integration-tests,@taquito/website,taquito-test-dapp --collectCoverage",
"lint": "lerna run lint",
"clean": "rm -rf ./node_modules/* && lerna clean --yes",
"commit": "git-cz",
Expand Down
44 changes: 41 additions & 3 deletions packages/taquito-beacon-wallet/src/taquito-beacon-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ import {
WalletProvider,
WalletTransferParams,
} from '@taquito/taquito';
import {
InvalidSignatureError,
ValidationResult,
b58cdecode,
b58cencode,
buf2hex,
invalidDetail,
isValidPrefix,
prefix,
verifySignature,
} from '@taquito/utils';
import { SignatureVerificationError } from '@taquito/core';
import toBuffer from 'typedarray-to-buffer';

export { VERSION } from './version';
export { BeaconWalletNotInitialized, MissingRequiredScopes } from './errors';
Expand Down Expand Up @@ -199,11 +212,36 @@ export class BeaconWallet implements WalletProvider {
}

async sign(signingRequest: { payload: string }) {
const response = await this.client.requestSignPayload({
payload: signingRequest.payload,
const watermarkedBytes = '03' + signingRequest.payload;
const { signature } = await this.client.requestSignPayload({
payload: watermarkedBytes,
signingType: SigningType.OPERATION,
});
return response.signature;
const pref = signature.startsWith('sig')
? signature.substring(0, 3)
: signature.substring(0, 5);

if (!isValidPrefix(pref)) {
throw new InvalidSignatureError(
signature,
invalidDetail(ValidationResult.NO_PREFIX_MATCHED) + ` from the wallet.`
);
}

const decoded = b58cdecode(signature, prefix[pref]);

const pk = await this.getPublicKey();
const signatureVerified = verifySignature(watermarkedBytes, pk, signature);
if (!signatureVerified) {
throw new SignatureVerificationError(watermarkedBytes, signature);
}

return {
bytes: signingRequest.payload,
sig: b58cencode(decoded, prefix.sig),
prefixSig: signature,
sbytes: signingRequest.payload + buf2hex(toBuffer(decoded)),
};
}

async getPublicKey(): Promise<string> {
Expand Down
13 changes: 13 additions & 0 deletions packages/taquito-core/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,16 @@ export class PublicKeyNotFoundError extends TaquitoError {
this.message = `Public key not found of this address "${pkh}" in either wallet or contract API.`;
}
}

/**
* @category Error
* @description Error
*/
export class SignatureVerificationError extends TaquitoError {
public name = 'SignatureVerificationFailedError';
constructor(public readonly bytes: string, public readonly signature: string) {
super();
this.name = 'SignatureVerificationFailedError';
this.message = `Invalid signature of bytes failed verification agaisnt public key.`;
}
}
13 changes: 0 additions & 13 deletions packages/taquito-remote-signer/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,3 @@ export class PublicKeyVerificationError extends TaquitoError {
this.message = `Requested pk "${requestedPk}" has pkh "${requestedPkh}" deesn't match initialized pkh "${initializedPkh}."`;
}
}

/**
* @category Error
* @description Error
*/
export class SignatureVerificationError extends TaquitoError {
public name = 'SignatureVerificationFailedError';
constructor(public readonly bytes: string, public readonly signature: string) {
super();
this.name = 'SignatureVerificationFailedError';
this.message = `Invalid signature of bytes failed verification agaisnt public key.`;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ import {
BadSigningDataError,
OperationNotAuthorizedError,
PublicKeyVerificationError,
SignatureVerificationError,
} from './errors';
import { Signer } from '@taquito/taquito';
import {
InvalidSignatureError,
InvalidKeyHashError,
ProhibitedActionError,
PublicKeyNotFoundError,
SignatureVerificationError,
} from '@taquito/core';

interface PublicKeyResponse {
Expand Down
7 changes: 6 additions & 1 deletion packages/taquito/src/wallet/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ export interface WalletProvider {
/**
* @description Request the wallet to sign a payload
*/
sign(signingRequest: { payload: string }): Promise<string>;
sign(signingRequest: { payload: string }): Promise<{
bytes: string;
sig: string;
prefixSig: string;
sbytes: string;
}>;

/**
* @description Get the public key from the wallet
Expand Down
7 changes: 3 additions & 4 deletions packages/taquito/src/wallet/legacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,11 @@ export class LegacyWalletProvider implements WalletProvider {
return op.hash;
}

async sign(signingRequest: { payload: string }): Promise<string> {
const response = await this.context.signer.sign(signingRequest.payload, new Uint8Array([3]));
return response.sbytes;
sign(signingRequest: { payload: string }) {
return this.context.signer.sign(signingRequest.payload, new Uint8Array([3]));
}

getPublicKey(): Promise<string> {
getPublicKey() {
return this.context.signer.publicKey();
}
}
6 changes: 1 addition & 5 deletions packages/taquito/src/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,7 @@ export class Wallet {
(await this.context.readProvider.getNextProtocol('head'));
const forger = new LocalForger(protocolHash);
const forgedBytes = await forger.forge(forgeable);
const signature = await this.walletProvider.sign({ payload: forgedBytes });
return {
bytes: forgedBytes,
sbytes: signature,
};
return await this.walletProvider.sign({ payload: forgedBytes });
}

/**
Expand Down

0 comments on commit 525afd7

Please sign in to comment.