Skip to content

Commit

Permalink
refactor: bitcoin send transaction (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
meeh0w authored Sep 5, 2024
1 parent 8730f13 commit 3557334
Show file tree
Hide file tree
Showing 81 changed files with 2,238 additions and 2,538 deletions.
15 changes: 15 additions & 0 deletions .releaserc.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,21 @@ const releaseReplaceSetting = [
],
countMatches: true,
},
{
files: ['dist/js/inpage.js'],
from: 'CORE_EXTENSION_VERSION',
// Replace CORE_EXTENSION_VERSION string to the next release number in the inpage.js file
to: `<%= _.replace(nextRelease.version, /[^0-9.]/g, '') %>`,
results: [
{
file: 'dist/js/inpage.js',
hasChanged: true,
numMatches: 1,
numReplacements: 1,
},
],
countMatches: true,
},
],
},
];
Expand Down
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ module.exports = {
EVM_PROVIDER_INFO_ICON: 'EVM_PROVIDER_INFO_ICON',
EVM_PROVIDER_INFO_DESCRIPTION: 'EVM_PROVIDER_INFO_DESCRIPTION',
EVM_PROVIDER_INFO_RDNS: 'EVM_PROVIDER_INFO_RDNS',
CORE_EXTENSION_VERSION: 'CORE_EXTENSION_VERSION',
},
};
14 changes: 9 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,23 @@
},
"dependencies": {
"@avalabs/avalanchejs": "4.0.5",
"@avalabs/bitcoin-module": "0.0.0-feat-add-core-version-to-evm-p-20240903160850",
"@avalabs/bridge-unified": "2.1.0",
"@avalabs/core-bridge-sdk": "3.1.0-alpha.4",
"@avalabs/core-chains-sdk": "3.1.0-alpha.4",
"@avalabs/core-coingecko-sdk": "3.1.0-alpha.4",
"@avalabs/core-covalent-sdk": "3.1.0-alpha.4",
"@avalabs/core-etherscan-sdk": "3.1.0-alpha.4",
"@avalabs/core-k2-components": "4.18.0-alpha.47",
"@avalabs/core-snowtrace-sdk": "3.1.0-alpha.4",
"@avalabs/core-token-prices-sdk": "3.1.0-alpha.4",
"@avalabs/core-utils-sdk": "3.1.0-alpha.4",
"@avalabs/core-wallets-sdk": "3.1.0-alpha.4",
"@avalabs/evm-module": "0.0.0-feat-add-core-version-to-evm-p-20240903160850",
"@avalabs/glacier-sdk": "3.1.0-alpha.4",
"@avalabs/hw-app-avalanche": "0.14.1",
"@avalabs/core-k2-components": "4.18.0-alpha.47",
"@avalabs/types": "3.1.0-alpha.3",
"@avalabs/vm-module-types": "0.3.0",
"@avalabs/bitcoin-module": "0.3.0",
"@avalabs/evm-module": "0.3.0",
"@avalabs/vm-module-types": "0.0.0-feat-add-core-version-to-evm-p-20240903160850",
"@blockaid/client": "0.10.0",
"@coinbase/cbpay-js": "1.6.0",
"@cubist-labs/cubesigner-sdk": "0.3.28",
Expand All @@ -55,6 +55,7 @@
"@ledgerhq/hw-app-eth": "6.36.1",
"@ledgerhq/hw-transport-webusb": "6.28.6",
"@metamask/eth-sig-util": "4.0.1",
"@metamask/rpc-errors": "6.3.0",
"@noble/hashes": "1.3.2",
"@openzeppelin/contracts": "4.9.6",
"@sentry/browser": "7.66.0",
Expand Down Expand Up @@ -244,7 +245,10 @@
"@avalabs/bitcoin-module>@avalabs/core-wallets-sdk>@avalabs/hw-app-avalanche>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>eip55>keccak": false,
"@avalabs/bitcoin-module>@avalabs/core-wallets-sdk>@ledgerhq/hw-app-btc>bitcoinjs-lib>bip32>tiny-secp256k1": false,
"@avalabs/bitcoin-module>@avalabs/core-wallets-sdk>hdkey>secp256k1": false,
"@avalabs/evm-module": false
"@avalabs/evm-module": false,
"@avalabs/bitcoin-module>@avalabs/vm-module-types>@avalabs/core-wallets-sdk>@avalabs/hw-app-avalanche>@ledgerhq/hw-app-eth>@ledgerhq/domain-service>eip55>keccak": false,
"@avalabs/bitcoin-module>@avalabs/vm-module-types>@avalabs/core-wallets-sdk>@ledgerhq/hw-app-btc>bitcoinjs-lib>bip32>tiny-secp256k1": false,
"@avalabs/bitcoin-module>@avalabs/vm-module-types>@avalabs/core-wallets-sdk>hdkey>secp256k1": false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import {
import sentryCaptureException, {
SentryExceptionTypes,
} from '@src/monitoring/sentryCaptureException';
import { ModuleManager } from '@src/background/vmModules/ModuleManager';
import { ActiveNetworkMiddleware } from '../middlewares/ActiveNetworkMiddleware';

/**
* This needs to be a controller per dApp, to separate messages
Expand All @@ -55,7 +57,8 @@ export class DAppConnectionController implements ConnectionController {
private permissionsService: PermissionsService,
private accountsService: AccountsService,
private networkService: NetworkService,
private lockService: LockService
private lockService: LockService,
private moduleManager: ModuleManager
) {
this.onRequest = this.onRequest.bind(this);
this.disconnect = this.disconnect.bind(this);
Expand All @@ -79,7 +82,8 @@ export class DAppConnectionController implements ConnectionController {
this.accountsService,
this.lockService
),
DAppRequestHandlerMiddleware(this.handlers, this.networkService),
ActiveNetworkMiddleware(this.networkService),
DAppRequestHandlerMiddleware(this.handlers, this.moduleManager),
LoggerMiddleware(SideToLog.RESPONSE)
);

Expand Down
5 changes: 4 additions & 1 deletion src/background/connections/dAppConnection/models.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Maybe } from '@avalabs/core-utils-sdk';
import { RpcResponse } from '@avalabs/vm-module-types';
import { DomainMetadata } from '@src/background/models';
import { EthereumProviderError } from 'eth-rpc-errors';
import { SerializedEthereumRpcError } from 'eth-rpc-errors/dist/classes';
Expand Down Expand Up @@ -71,6 +72,7 @@ export interface JsonRpcRequest<Method extends string = any, Params = unknown> {
readonly id: string;
readonly method: 'provider_request';
readonly params: JsonRpcRequestParams<Method, Params>;
readonly context?: { tabId?: number } & Record<string, unknown>;
}

interface JsonRpcRequestPayloadBase<Method extends string = any> {
Expand Down Expand Up @@ -100,4 +102,5 @@ export interface JsonRpcFailure {
}
export declare type JsonRpcResponse<T = unknown> =
| JsonRpcSuccess<T>
| JsonRpcFailure;
| JsonRpcFailure
| RpcResponse;
2 changes: 0 additions & 2 deletions src/background/connections/dAppConnection/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import { registry } from 'tsyringe';
import { AvalancheGetAccountPubKeyHandler } from '@src/background/services/accounts/handlers/avalanche_getAccountPubKey';
import { AvalancheSendTransactionHandler } from '@src/background/services/wallet/handlers/avalanche_sendTransaction';
import { AvalancheGetAddressesInRangeHandler } from '@src/background/services/accounts/handlers/avalanche_getAddressesInRange';
import { BitcoinSendTransactionHandler } from '@src/background/services/wallet/handlers/bitcoin_sendTransaction';
import { AvalancheSignTransactionHandler } from '@src/background/services/wallet/handlers/avalanche_signTransaction';
import { AvalancheSignMessageHandler } from '@src/background/services/messages/handlers/avalanche_signMessage';

Expand All @@ -54,7 +53,6 @@ import { AvalancheSignMessageHandler } from '@src/background/services/messages/h
{ token: 'DAppRequestHandler', useToken: AvalancheGetAccountPubKeyHandler },
{ token: 'DAppRequestHandler', useToken: AvalancheSendTransactionHandler },
{ token: 'DAppRequestHandler', useToken: AvalancheSignTransactionHandler },
{ token: 'DAppRequestHandler', useToken: BitcoinSendTransactionHandler },
{ token: 'DAppRequestHandler', useToken: AvalancheSignMessageHandler },
{
token: 'DAppRequestHandler',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { injectable, injectAll, injectAllWithTransform } from 'tsyringe';
import { Runtime } from 'webextension-polyfill';
import { runtime, Runtime } from 'webextension-polyfill';
import { DEFERRED_RESPONSE, Pipeline } from '../middlewares/models';
import { ExtensionRequestHandlerMiddleware } from '../middlewares/ExtensionRequestHandlerMiddleware';
import {
Expand Down Expand Up @@ -30,6 +30,9 @@ import sentryCaptureException, {
} from '@src/monitoring/sentryCaptureException';

import { DappHandlerToExtensionHandlerTransformer } from './DappHandlerToExtensionHandlerTransformer';
import { NetworkService } from '@src/background/services/network/NetworkService';
import { ModuleManager } from '@src/background/vmModules/ModuleManager';
import { ActiveNetworkMiddleware } from '../middlewares/ActiveNetworkMiddleware';

@injectable()
export class ExtensionConnectionController implements ConnectionController {
Expand All @@ -49,7 +52,9 @@ export class ExtensionConnectionController implements ConnectionController {
DappHandlerToExtensionHandlerTransformer
)
private dappHandlers: ExtensionRequestHandler<any, any>[],
@injectAll('DAppEventEmitter') private dappEmitters: DAppEventEmitter[]
@injectAll('DAppEventEmitter') private dappEmitters: DAppEventEmitter[],
private networkService: NetworkService,
private moduleManager: ModuleManager
) {
this.onMessage = this.onMessage.bind(this);
this.disconnect = this.disconnect.bind(this);
Expand All @@ -60,10 +65,11 @@ export class ExtensionConnectionController implements ConnectionController {
this.connection = connection;

this.pipeline = RequestProcessorPipeline(
ExtensionRequestHandlerMiddleware([
...this.handlers,
...this.dappHandlers,
])
ActiveNetworkMiddleware(this.networkService),
ExtensionRequestHandlerMiddleware(
[...this.handlers, ...this.dappHandlers],
this.moduleManager
)
);

connectionLog('Extension Provider');
Expand Down Expand Up @@ -107,6 +113,15 @@ export class ExtensionConnectionController implements ConnectionController {
// always start with authenticated false, middlewares take care of context updates
authenticated: false,
request: deserializedRequest,
// Extension does not connect through ChainAgnosticProvider,
// therefore its requests do not have domainMetadata populated.
domainMetadata: {
domain: runtime.id,
url: runtime.getURL(''),
tabId: deserializedRequest.params.request.tabId,
icon: runtime.getManifest().icons?.['192'],
name: runtime.getManifest().name,
},
})
);

Expand Down
35 changes: 35 additions & 0 deletions src/background/connections/middlewares/ActiveNetworkMiddleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { NetworkService } from '@src/background/services/network/NetworkService';

import { JsonRpcRequest, JsonRpcResponse } from '../dAppConnection/models';

import { Middleware } from './models';
import {
ExtensionConnectionMessage,
ExtensionConnectionMessageResponse,
} from '../models';

export function ActiveNetworkMiddleware(
networkService: NetworkService
): Middleware<
JsonRpcRequest | ExtensionConnectionMessage,
JsonRpcResponse | ExtensionConnectionMessageResponse
> {
return async (context, next, error) => {
const { scope } = context.request.params;

if (scope) {
const network = await networkService.getNetwork(
context.request.params.scope
);

if (!network) {
error(new Error(`Unrecognized network: ${scope}`));
return;
}

context.network = network;
}

next();
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { DEFERRED_RESPONSE } from '@src/background/connections/middlewares/model
import { Middleware } from './models';
import { resolve } from '@src/utils/promiseResolver';
import { engine } from '@src/utils/jsonRpcEngine';
import { NetworkService } from '@src/background/services/network/NetworkService';
import { DAppRequestHandler } from '../dAppConnection/DAppRequestHandler';
import { ethErrors } from 'eth-rpc-errors';
import {
Expand All @@ -11,10 +10,11 @@ import {
JsonRpcRequestParams,
JsonRpcResponse,
} from '../dAppConnection/models';
import { ModuleManager } from '@src/background/vmModules/ModuleManager';

export function DAppRequestHandlerMiddleware(
handlers: DAppRequestHandler[],
networkService: NetworkService
moduleManager: ModuleManager
): Middleware<JsonRpcRequest, JsonRpcResponse<unknown>> {
const handlerMap = handlers.reduce((acc, handler) => {
for (const method of handler.methods) {
Expand All @@ -27,6 +27,15 @@ export function DAppRequestHandlerMiddleware(
const handler = handlerMap.get(context.request.params.request.method);
// Call correct handler method based on authentication status
let promise: Promise<JsonRpcResponse<unknown>>;

if (!context.domainMetadata) {
context.response = {
error: ethErrors.rpc.invalidRequest('Unknown request domain'),
};

return next();
}

if (handler) {
const params: JsonRpcRequestParams<DAppProviderRequest> = {
...context.request.params,
Expand All @@ -39,20 +48,44 @@ export function DAppRequestHandlerMiddleware(
? handler.handleAuthenticated(params)
: handler.handleUnauthenticated(params);
} else {
const activeNetwork = await networkService.getNetwork(
context.request.params.scope
const [module] = await resolve(
moduleManager.loadModule(
context.request.params.scope,
context.request.params.request.method
)
);

if (!activeNetwork) {
if (!context.network) {
promise = Promise.reject(ethErrors.provider.disconnected());
} else {
promise = engine(activeNetwork).then((e) =>
e.handle<unknown, unknown>({
...context.request.params.request,
id: crypto.randomUUID(),
jsonrpc: '2.0',
})
);
if (module) {
promise = module.onRpcRequest(
{
chainId: context.network.caipId,
dappInfo: {
icon: context.domainMetadata.icon ?? '',
name: context.domainMetadata.name ?? '',
url: context.domainMetadata.url ?? '',
},
requestId: context.request.id,
sessionId: context.request.params.sessionId,
method: context.request.params.request.method,
params: context.request.params.request.params,
// Do not pass context from unknown sources.
// This field is for our internal use only (only used with extension's direct connection)
context: undefined,
},
context.network
);
} else {
promise = engine(context.network).then((e) =>
e.handle<unknown, unknown>({
...context.request.params.request,
id: crypto.randomUUID(),
jsonrpc: '2.0',
})
);
}
}
}

Expand Down
Loading

0 comments on commit 3557334

Please sign in to comment.