Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/snaps.git"
},
"source": {
"shasum": "/yD9JVMe1ppdLCocldK6/6D9Cx0j1+iZQy5Z5INLlEU=",
"shasum": "HQcHCmjI/cTIiFTeAr/PywSGgXUWYUi/otWoHST40h4=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
59 changes: 37 additions & 22 deletions packages/examples/packages/ethereum-provider/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,38 +20,53 @@ describe('onRpcRequest', () => {
});
});

describe('getGasPrice', () => {
const MOCK_GAS_PRICE = '0x387c64b64';

it('returns the current gas price', async () => {
describe('getGenesisBlock', () => {
// Ethereum Mainnet
const GENESIS_BLOCK = {
difficulty: '0x400000000',
extraData:
'0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa',
gasLimit: '0x1388',
gasUsed: '0x0',
hash: '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3',
logsBloom:
'0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
miner: '0x0000000000000000000000000000000000000000',
mixHash:
'0x0000000000000000000000000000000000000000000000000000000000000000',
nonce: '0x0000000000000042',
number: '0x0',
parentHash:
'0x0000000000000000000000000000000000000000000000000000000000000000',
receiptsRoot:
'0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
sha3Uncles:
'0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',
size: '0x21c',
stateRoot:
'0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544',
timestamp: '0x0',
transactions: [],
transactionsRoot:
'0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
uncles: [],
};

it('returns the genesis block', async () => {
const { request, mockJsonRpc } = await installSnap();

// To avoid relying on the network, we mock the response from the Ethereum
// provider.
mockJsonRpc({
method: 'eth_gasPrice',
result: MOCK_GAS_PRICE,
});

const response = await request({
method: 'getGasPrice',
method: 'eth_getBlockByNumber',
result: GENESIS_BLOCK,
});

expect(response).toRespondWith(MOCK_GAS_PRICE);
});
});

describe('getVersion', () => {
const MOCK_VERSION = '1'; // Ethereum Mainnet

it('returns the current network version', async () => {
const { request } = await installSnap();

const response = await request({
method: 'getVersion',
method: 'getGenesisBlock',
});

expect(response).toRespondWith(MOCK_VERSION);
expect(response).toRespondWith(GENESIS_BLOCK);
});
});

Expand Down
57 changes: 21 additions & 36 deletions packages/examples/packages/ethereum-provider/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
stringToBytes,
bytesToHex,
hexToNumber,
numberToHex,
} from '@metamask/utils';

import type {
Expand All @@ -29,60 +30,47 @@ async function switchChain(chainId: Hex) {
}

/**
* Get the current gas price using the `ethereum` global. This is essentially
* Get the current chain ID using the `ethereum` global. This is essentially
* the same as the `window.ethereum` global, but does not have access to all
* methods.
*
* Note that using the `ethereum` global requires the
* `endowment:ethereum-provider` permission.
*
* @returns The current gas price as a hexadecimal string.
* @returns The current chain ID as a string.
* @see https://docs.metamask.io/snaps/reference/permissions/#endowmentethereum-provider
*/
async function getGasPrice() {
const gasPrice = await ethereum.request<Hex>({ method: 'eth_gasPrice' });
assert(gasPrice, 'Ethereum provider did not return a gas price.');

return gasPrice;
}
async function getChainId() {
const chainId = await ethereum.request<string>({
method: 'eth_chainId',
});

/**
* Get the current network version using the `ethereum` global. This is
* essentially the same as the `window.ethereum` global, but does not have
* access to all methods.
*
* Note that using the `ethereum` global requires the
* `endowment:ethereum-provider` permission.
*
* @returns The current network version as a string.
* @see https://docs.metamask.io/snaps/reference/permissions/#endowmentethereum-provider
*/
async function getVersion() {
const version = await ethereum.request<string>({ method: 'net_version' });
assert(version, 'Ethereum provider did not return a version.');
assert(chainId, 'Ethereum provider did not return a chain ID.');

return version;
return chainId;
}

/**
* Get the current chain ID using the `ethereum` global. This is essentially
* Get a block by number using the `ethereum` global. This is essentially
* the same as the `window.ethereum` global, but does not have access to all
* methods.
*
* Note that using the `ethereum` global requires the
* `endowment:ethereum-provider` permission.
*
* @returns The current chain ID as a string.
* @param blockNumber - The block number.
* @returns Information about the requested block.
* @see https://docs.metamask.io/snaps/reference/permissions/#endowmentethereum-provider
*/
async function getChainId() {
const chainId = await ethereum.request<string>({
method: 'eth_chainId',
async function getBlock(blockNumber: number) {
const block = await ethereum.request<string>({
method: 'eth_getBlockByNumber',
params: [numberToHex(blockNumber), false],
});

assert(chainId, 'Ethereum provider did not return a chain ID.');
assert(block, 'Ethereum provider did not return a block.');

return chainId;
return block;
}

/**
Expand Down Expand Up @@ -249,18 +237,15 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => {
await switchChain(chainId);

switch (request.method) {
case 'getGasPrice':
return await getGasPrice();

case 'getVersion':
return await getVersion();

case 'getChainId':
return await getChainId();

case 'getAccounts':
return await getAccounts();

case 'getGenesisBlock':
return await getBlock(0);

case 'personalSign': {
const params = request.params as PersonalSignParams;
const accounts = await getAccounts();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const EthereumProvider: FunctionComponent = () => {
};

const handleGetChainId = () => handleSubmit('getChainId');
const handleGetGenesisBlock = () => handleSubmit('getGenesisBlock');
const handleGetAccounts = () => handleSubmit('getAccounts');

return (
Expand All @@ -50,6 +51,15 @@ export const EthereumProvider: FunctionComponent = () => {
>
Get Chain ID
</Button>
<Button
variant="secondary"
id="sendGenesisBlockEthProvider"
className="mb-3"
disabled={isLoading}
onClick={handleGetGenesisBlock}
>
Get Genesis Block
</Button>
<Button
variant="primary"
id="sendEthproviderAccounts"
Expand Down
Loading