Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/lw 10575 fix roundtrip error in base wallet #1321

Merged
merged 2 commits into from
Jun 10, 2024
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
6 changes: 5 additions & 1 deletion packages/wallet/src/Wallets/BaseWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ export class BaseWallet implements ObservableWallet {

async finalizeTx({
tx,
bodyCbor,
signingOptions,
signingContext,
auxiliaryData,
Expand All @@ -605,8 +606,11 @@ export class BaseWallet implements ObservableWallet {
};

const emptyWitness = { signatures: new Map() };

// The Witnesser takes a serializable transaction. We cant build that from the hash alone, if
// the bodyCbor is available, use that instead of the coreTx type to build the transaction.
const transaction = new Serialization.Transaction(
Serialization.TransactionBody.fromCore(tx.body),
bodyCbor ? Serialization.TransactionBody.fromCbor(bodyCbor) : Serialization.TransactionBody.fromCore(tx.body),
Serialization.TransactionWitnessSet.fromCore({ ...emptyWitness, ...witness }),
auxiliaryData ? Serialization.AuxiliaryData.fromCore(auxiliaryData) : undefined
);
Expand Down
6 changes: 5 additions & 1 deletion packages/wallet/src/cip30.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,11 @@ const baseCip30WalletApi = (
);
const {
witness: { signatures }
} = await wallet.finalizeTx({ signingContext: { sender }, tx: { ...coreTx, hash } });
} = await wallet.finalizeTx({
bodyCbor: txDecoded.body().toCbor(),
signingContext: { sender },
tx: { ...coreTx, hash }
});

// If partialSign is true, the wallet only tries to sign what it can. However, if
// signatures size is 0 then throw.
Expand Down
6 changes: 4 additions & 2 deletions packages/wallet/src/services/WalletUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface WalletOutputValidatorContext {
}

export type WalletUtilContext = WalletOutputValidatorContext &
InputResolverContext & { chainHistoryProvider: ChainHistoryProvider };
InputResolverContext & { chainHistoryProvider?: ChainHistoryProvider };

export const createInputResolver = ({ utxo, transactions }: InputResolverContext): Cardano.InputResolver => ({
async resolveInput(input: Cardano.TxIn, options?: Cardano.ResolveOptions) {
Expand Down Expand Up @@ -131,7 +131,9 @@ export const combineInputResolvers = (...resolvers: Cardano.InputResolver[]): Ca
*/
export const createWalletUtil = (context: WalletUtilContext) => ({
...createOutputValidator({ protocolParameters: () => firstValueFrom(context.protocolParameters$) }),
...combineInputResolvers(createInputResolver(context), createBackendInputResolver(context.chainHistoryProvider))
...(context.chainHistoryProvider
? combineInputResolvers(createInputResolver(context), createBackendInputResolver(context.chainHistoryProvider))
: createInputResolver(context))
});

export type WalletUtil = ReturnType<typeof createWalletUtil>;
Expand Down
3 changes: 2 additions & 1 deletion packages/wallet/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import { BalanceTracker, DelegationTracker, TransactionsTracker, UtxoTracker } f
import { Cip30DataSignature } from '@cardano-sdk/dapp-connector';
import { Ed25519PublicKeyHex } from '@cardano-sdk/crypto';
import { GroupedAddress, MessageSender, SignTransactionContext, WitnessedTx, cip8 } from '@cardano-sdk/key-management';
import { HexBlob, Shutdown } from '@cardano-sdk/util';
import { InitializeTxProps, InitializeTxResult, TxBuilder, TxContext } from '@cardano-sdk/tx-construction';
import { Observable } from 'rxjs';
import { PubStakeKeyAndStatus } from './services/PublicStakeKeysTracker';
import { Shutdown } from '@cardano-sdk/util';

export type Assets = Map<Cardano.AssetId, Asset.AssetInfo>;

Expand Down Expand Up @@ -45,6 +45,7 @@ export interface SyncStatus extends Shutdown {

export type FinalizeTxProps = Omit<TxContext, 'signingContext'> & {
tx: Cardano.TxBodyWithHash;
bodyCbor?: HexBlob;
signingContext?: Partial<SignTransactionContext>;
};

Expand Down
19 changes: 19 additions & 0 deletions packages/wallet/test/PersonalWallet/methods.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ const { mockChainHistoryProvider, mockRewardsProvider, utxo } = mocks;
const serializedForeignTx =
'84a60081825820260aed6e7a24044b1254a87a509468a649f522a4e54e830ac10f27ea7b5ec61f01018383581d70b429738bd6cc58b5c7932d001aa2bd05cfea47020a556c8c753d44361a004c4b40582007845f8f3841996e3d8157954e2f5e2fb90465f27112fc5fe9056d916fae245b82583900b1814238b0d287a8a46ce7348c6ad79ab8995b0e6d46010e2d9e1c68042f1946335c498d2e7556c5c647c4649c6a69d2b645cd1428a339ba1a0463676982583900b1814238b0d287a8a46ce7348c6ad79ab8995b0e6d46010e2d9e1c68042f1946335c498d2e7556c5c647c4649c6a69d2b645cd1428a339ba821a00177a6ea2581c648823ffdad1610b4162f4dbc87bd47f6f9cf45d772ddef661eff198a5447742544319271044774554481a0031f9194577444f47451a0056898d4577555344431a000fc589467753484942411a000103c2581c659ab0b5658687c2e74cd10dba8244015b713bf503b90557769d77a7a14a57696e675269646572731a02269552021a0002e665031a02414F03081a02414EFA0b58204107eada931c72a600a6e3305bd22c7aeb9ada7c3f6823b155f4db85de36a69aa20081825820e686ade5bc97372f271fd2abc06cfd96c24b3d9170f9459de1d8e3dd8fd385575840653324a9dddad004f05a8ac99fa2d1811af5f00543591407fb5206cfe9ac91bb1412404323fa517e0e189684cd3592e7f74862e3f16afbc262519abec958180c0481d8799fd8799fd8799fd8799f581cb1814238b0d287a8a46ce7348c6ad79ab8995b0e6d46010e2d9e1c68ffd8799fd8799fd8799f581c042f1946335c498d2e7556c5c647c4649c6a69d2b645cd1428a339baffffffff581cb1814238b0d287a8a46ce7348c6ad79ab8995b0e6d46010e2d9e1c681b000001863784a12ed8799fd8799f4040ffd8799f581c648823ffdad1610b4162f4dbc87bd47f6f9cf45d772ddef661eff1984577444f4745ffffffd8799fd87980190c8efffff5f6';

const geniusYieldTx = Serialization.Transaction.fromCbor(
TxCBOR(
'84aa0081825820c816519a759e300acc16d1e2812500392c85ae6d5af886dd154c9084a610a120010182a30058391044376a5f63342097a4f20401088c62da272639e60644a9ec1d70f4441d3554e12c8aed91818a0600a57bea9d50e509beda567387d124731501821a3bf7de20a1581c53827a77e4ed3d5c211706708c0aa9b9a3be19db901b1cbf7fa515b8a1582021e6a58421ea7762aeeedf1e217c9488592cd0b94cc655ab633506d9f95ed5f301028200582093d1a590f45777813b41443657b05572ed9fbecd885ce731955aab2d238b7da4a20058390099f8985db8b9076f61ecec59eca67e30224dc20afb40491aecc6aa971d3554e12c8aed91818a0600a57bea9d50e509beda567387d1247315011b0000000217c0f5a9021a000432ca07582037c0555635ab7e45ec39bd8feb873080d036c9a67c4cdd0c85e1c5291b0482f209a1581c53827a77e4ed3d5c211706708c0aa9b9a3be19db901b1cbf7fa515b8a1582021e6a58421ea7762aeeedf1e217c9488592cd0b94cc655ab633506d9f95ed5f3010b5820916cc9dc5a9e6e7710d5ab64f0b5624235dd43067e30835b1e3ac6ee995c9d280d81825820c816519a759e300acc16d1e2812500392c85ae6d5af886dd154c9084a610a1200010a20058390099f8985db8b9076f61ecec59eca67e30224dc20afb40491aecc6aa971d3554e12c8aed91818a0600a57bea9d50e509beda567387d1247315011a0045ff11111a00064c2f128282582016647d6365020555d905d6e0edcf08b90a567886f875b40b3d7cec1c704826240082582016647d6365020555d905d6e0edcf08b90a567886f875b40b3d7cec1c7048262401a20481d8799f581c99f8985db8b9076f61ecec59eca67e30224dc20afb40491aecc6aa97d8799fd8799f581c99f8985db8b9076f61ecec59eca67e30224dc20afb40491aecc6aa97ffd8799fd8799fd8799f581c1d3554e12c8aed91818a0600a57bea9d50e509beda567387d1247315ffffffffd8799f4040ff1a3b9aca001a3b9aca00d8799f581cc6e65ba7878b2f8ea0ad39287d3e2fd256dc5c4160fc19bdf4c4d87e457447454e53ffd8799f0101ff582021e6a58421ea7762aeeedf1e217c9488592cd0b94cc655ab633506d9f95ed5f3d87a80d87a80001a000f42401a000f4240d8799f1a000f42401a002dc6c000ff00ff0581840100d8799fd8799fd8799f5820c816519a759e300acc16d1e2812500392c85ae6d5af886dd154c9084a610a120ff01ffff821a000b16161a10bcda52f5d90103a100a11902a2a1636d736781781947656e6975735969656c643a204f7264657220706c61636564'
)
);

const outputs = [
{
address: Cardano.PaymentAddress(
Expand Down Expand Up @@ -238,6 +244,19 @@ describe('BaseWallet methods', () => {

expect(witnessSpy).toBeCalledWith(expect.anything(), expect.objectContaining({ sender }), void 0);
});

it('uses the original CBOR to create the serializable transaction if given', async () => {
const sender = { url: 'https://lace.io' };
const witnessSpy = jest.spyOn(witnesser, 'witness');
const txInternals = await wallet.initializeTx(props);
await wallet.finalizeTx({
bodyCbor: geniusYieldTx.body().toCbor(),
signingContext: { sender },
tx: txInternals
});

expect(witnessSpy).toBeCalledWith(geniusYieldTx, expect.objectContaining({ sender }), void 0);
});
});

describe('submitTx', () => {
Expand Down
Loading