Skip to content

Commit

Permalink
Merge pull request #265 from near/SQAC-114-create-utils-package
Browse files Browse the repository at this point in the history
refactor: Created utils package
  • Loading branch information
amirsaran3 authored May 17, 2022
2 parents 4be8a6f + 2a3837b commit 44b08de
Show file tree
Hide file tree
Showing 24 changed files with 553 additions and 307 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"build:near-wallet": "nx run-many --target=build --projects=near-wallet --configuration=production",
"build:sender": "nx run-many --target=build --projects=sender --configuration=production",
"build:wallet-connect": "nx run-many --target=build --projects=wallet-connect --configuration=production",
"build:wallet-utils": "nx run-many --target=build --projects=wallet-utils --configuration=production",
"lint": "nx workspace-lint && nx run-many --target=lint --all --parallel",
"lint:fix": "nx run-many --target=lint --all --fix",
"serve:react": "nx serve react",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ export {
AddKeyAction,
DeleteKeyAction,
DeleteAccountAction,
AddKeyPermission,
} from "./lib/wallet";

export { FinalExecutionOutcome } from "near-api-js/lib/providers";

export { transformActions } from "./lib/wallet";
export { waitFor } from "./lib/helpers";
170 changes: 0 additions & 170 deletions packages/core/src/lib/wallet/transactions.spec.ts

This file was deleted.

6 changes: 3 additions & 3 deletions packages/core/src/lib/wallet/transactions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Action } from "./transactions.types";
import { AddKeyPermission } from "./transactions.types";
import { transactions, utils } from "near-api-js";
import { BN } from "bn.js";

import { Action, AddKeyPermission } from "./transactions.types";
import BN from "bn.js";

const getAccessKey = (permission: AddKeyPermission) => {
if (permission === "FullAccess") {
Expand Down
128 changes: 63 additions & 65 deletions packages/ledger/src/lib/ledger.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { transactions as nearTransactions, utils } from "near-api-js";
import { isMobile } from "is-mobile";
import { TypedError } from "near-api-js/lib/utils/errors";
import isMobile from "is-mobile";
import { signTransactions } from "@near-wallet-selector/wallet-utils";
import {
WalletModuleFactory,
WalletBehaviourFactory,
JsonStorageService,
AccountState,
Account,
HardwareWallet,
transformActions,
Transaction,
Optional,
} from "@near-wallet-selector/core";

import { isLedgerSupported, LedgerClient, Subscription } from "./ledger-client";
import { Signer, utils } from "near-api-js";

interface LedgerAccount extends Account {
derivationPath: string;
Expand Down Expand Up @@ -64,6 +64,38 @@ const Ledger: WalletBehaviourFactory<HardwareWallet> = async ({
}) => {
const _state = await setupLedgerState(storage);

const signer: Signer = {
createKey: () => {
throw new Error("Not implemented");
},
getPublicKey: async (accountId) => {
const account = _state.accounts.find((a) => a.accountId === accountId);

if (!account) {
throw new Error("Failed to find public key for account");
}

return utils.PublicKey.from(account.publicKey);
},
signMessage: async (message, accountId) => {
const account = _state.accounts.find((a) => a.accountId === accountId);

if (!account) {
throw new Error("Failed to find account for signing");
}

const signature = await _state.client.sign({
data: message,
derivationPath: account.derivationPath,
});

return {
signature,
publicKey: utils.PublicKey.from(account.publicKey),
};
},
};

const getAccounts = (): Array<AccountState> => {
return _state.accounts.map((x) => ({
accountId: x.accountId,
Expand Down Expand Up @@ -146,63 +178,22 @@ const Ledger: WalletBehaviourFactory<HardwareWallet> = async ({
return accountIds[0];
};

const signTransactions = async (
const transformTransactions = (
transactions: Array<Optional<Transaction, "signerId">>
) => {
if (!_state.accounts.length) {
throw new Error(`${metadata.name} not connected`);
}

const signedTransactions: Array<nearTransactions.SignedTransaction> = [];

for (let i = 0; i < transactions.length; i++) {
const transaction = transactions[i];
const account = transaction.signerId
? _state.accounts.find((x) => x.accountId === transaction.signerId)
: _state.accounts[0];

if (!account) {
throw new Error("Invalid signer id: " + transaction.signerId);
): Array<Transaction> => {
return transactions.map((t) => {
if (!_state.accounts.length) {
throw new Error("Wallet not connected");
}

const { accountId, derivationPath, publicKey } = account;

const [block, accessKey] = await Promise.all([
provider.block({ finality: "final" }),
provider.viewAccessKey({ accountId, publicKey }),
]);

const tx = nearTransactions.createTransaction(
accountId,
utils.PublicKey.from(publicKey),
transaction.receiverId,
accessKey.nonce + i + 1,
transformActions(transaction.actions),
utils.serialize.base_decode(block.header.hash)
);

const serializedTx = utils.serialize.serialize(
nearTransactions.SCHEMA,
tx
);

const signature = await _state.client.sign({
data: serializedTx,
derivationPath,
});

const signedTx = new nearTransactions.SignedTransaction({
transaction: tx,
signature: new nearTransactions.Signature({
keyType: tx.publicKey.keyType,
data: signature,
}),
});
const signerId = t.signerId ? t.signerId : _state.accounts[0].accountId;

signedTransactions.push(signedTx);
}

return signedTransactions;
return {
receiverId: t.receiverId,
actions: t.actions,
signerId,
};
});
};

return {
Expand Down Expand Up @@ -272,15 +263,18 @@ const Ledger: WalletBehaviourFactory<HardwareWallet> = async ({
// Note: Connection must be triggered by user interaction.
await connectLedgerDevice();

const [signedTx] = await signTransactions([
{
signerId,
receiverId,
actions,
},
]);
const signedTransactions = await signTransactions(
transformTransactions([
{
receiverId,
actions,
},
]),
signer,
options.network.nodeUrl
);

return provider.sendTransaction(signedTx);
return provider.sendTransaction(signedTransactions[0]);
},

async signAndSendTransactions({ transactions }) {
Expand All @@ -293,7 +287,11 @@ const Ledger: WalletBehaviourFactory<HardwareWallet> = async ({
// Note: Connection must be triggered by user interaction.
await connectLedgerDevice();

const signedTransactions = await signTransactions(transactions);
const signedTransactions = await signTransactions(
transformTransactions(transactions),
signer,
options.network.nodeUrl
);

return Promise.all(
signedTransactions.map((signedTx) => provider.sendTransaction(signedTx))
Expand Down
Loading

0 comments on commit 44b08de

Please sign in to comment.