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: support starknet snap for metamask #450

Draft
wants to merge 7 commits into
base: next
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions wallets/provider-all/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@rango-dev/provider-leap-cosmos": "^0.21.1-next.3",
"@rango-dev/provider-math-wallet": "^0.21.1-next.3",
"@rango-dev/provider-metamask": "^0.21.1-next.3",
"@rango-dev/provider-starknet-snap": "^0.21.1-next.3",
"@rango-dev/provider-okx": "^0.21.1-next.3",
"@rango-dev/provider-phantom": "^0.21.1-next.3",
"@rango-dev/provider-safe": "^0.14.1-next.4",
Expand Down
2 changes: 2 additions & 0 deletions wallets/provider-all/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import * as okx from '@rango-dev/provider-okx';
import * as phantom from '@rango-dev/provider-phantom';
import * as safe from '@rango-dev/provider-safe';
import * as safepal from '@rango-dev/provider-safepal';
import * as starknetSnap from '@rango-dev/provider-starknet-snap';
import * as taho from '@rango-dev/provider-taho';
import * as tokenpocket from '@rango-dev/provider-tokenpocket';
import * as tronLink from '@rango-dev/provider-tron-link';
Expand Down Expand Up @@ -57,5 +58,6 @@ export const allProviders = (enviroments?: Enviroments) => {
frontier,
taho,
braavos,
starknetSnap,
];
};
4 changes: 3 additions & 1 deletion wallets/provider-braavos/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export function getBraavosInstance() {
const { starknet_braavos } = window;
if (!!starknet_braavos) return starknet_braavos;
if (!!starknet_braavos) {
return starknet_braavos;
}
return null;
}
8 changes: 3 additions & 5 deletions wallets/provider-metamask/src/signer.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import type { SignerFactory } from 'rango-types';

import { DefaultEvmSigner } from '@rango-dev/signer-evm';
import {
DefaultSignerFactory,
SignerFactory,
TransactionType as TxType,
} from 'rango-types';
import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types';

export default function getSigners(provider: any): SignerFactory {
const signers = new DefaultSignerFactory();
Expand Down
51 changes: 51 additions & 0 deletions wallets/provider-starknet-snap/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# [0.14.0](https://github.com/rango-exchange/rango-client/compare/[email protected]@0.14.0) (2023-08-03)



# [0.13.0](https://github.com/rango-exchange/rango-client/compare/[email protected]@0.13.0) (2023-08-01)



# [0.9.0](https://github.com/rango-exchange/rango-client/compare/[email protected]@0.9.0) (2023-07-31)



# [0.7.0](https://github.com/rango-exchange/rango-client/compare/[email protected]@0.7.0) (2023-07-11)
Comment on lines +1 to +13
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove content of this file




# [0.6.0](https://github.com/rango-exchange/rango-client/compare/[email protected]@0.6.0) (2023-07-11)


### Reverts

* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb))
* Revert "support for rango-types cjs format" ([4f5f55f](https://github.com/rango-exchange/rango-client/commit/4f5f55f96e8daa329588b932b19c291c30f339c4))



# [0.5.0](https://github.com/rango-exchange/rango-client/compare/[email protected]@0.5.0) (2023-05-31)



# [0.4.0](https://github.com/rango-exchange/rango-client/compare/[email protected]@0.4.0) (2023-05-31)



# [0.3.0](https://github.com/rango-exchange/rango-client/compare/[email protected]@0.3.0) (2023-05-30)



# [0.2.0](https://github.com/rango-exchange/rango-client/compare/[email protected]@0.2.0) (2023-05-30)



## [0.1.14](https://github.com/rango-exchange/rango-client/compare/[email protected]@0.1.14) (2023-05-15)


### Bug Fixes

* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90))



29 changes: 29 additions & 0 deletions wallets/provider-starknet-snap/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@rango-dev/provider-starknet-snap",
"version": "0.21.1-next.3",
"license": "MIT",
"type": "module",
"module": "./dist/index.js",
"main": "./dist/index.js",
"exports": {
".": "./dist/index.js"
},
"typings": "dist/index.d.ts",
"files": [
"dist",
"src"
],
"scripts": {
"build": "node ../../scripts/build/command.mjs --path wallets/provider-starknet-snap",
"clean": "rimraf dist",
"format": "prettier --write '{.,src}/**/*.{ts,tsx}'",
"lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore"
},
"dependencies": {
"@rango-dev/wallets-shared": "^0.21.1-next.3",
"rango-types": "^0.1.46"
},
"publishConfig": {
"access": "public"
}
}
1 change: 1 addition & 0 deletions wallets/provider-starknet-snap/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# @rango-dev/provider-metamask
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please update readme

77 changes: 77 additions & 0 deletions wallets/provider-starknet-snap/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import type { AccContract } from './types';

import { getCoinbaseInstance } from '@rango-dev/wallets-shared';

export const DEFAULT_SNAP_ID = 'npm:@consensys/starknet-snap';
export const SNAP_VERSION = '2.2.0';

export function metamask() {
const isCoinbaseWalletAvailable = !!getCoinbaseInstance();
const { ethereum } = window;

// Some wallets overriding the metamask. So we need to get it properly.
if (isCoinbaseWalletAvailable) {
// Getting intance from overrided structure from coinbase.
return getCoinbaseInstance('metamask');
}
if (!!ethereum && ethereum.isMetaMask) {
return ethereum;
}

return null;
}
export const isStarknetSnapInstalled = async (instance: any) =>
instance
.request({
method: 'wallet_invokeSnap',
params: {
snapId: DEFAULT_SNAP_ID,
request: {
method: 'ping',
},
},
})
.then(() => {
return true;
})
.catch((err: any) => {
console.log(err);
return false;
});

export const installStarknetSnap = async (instance: any) => {
const installed = await isStarknetSnapInstalled(instance);
if (!installed) {
instance.request({
method: 'wallet_requestSnaps',
params: {
[DEFAULT_SNAP_ID]: { version: SNAP_VERSION }, //Snap's version
},
});
}
};

export const getAccounts = async (
instance: any,
chainId: string
): Promise<AccContract[]> => {
const START_SCAN_INDEX = 0;
const MAX_SCANNED = 1;
const MAX_MISSED = 1;
const scannedAccounts = await instance.request({
method: 'wallet_invokeSnap',
params: {
snapId: DEFAULT_SNAP_ID,
request: {
method: 'starkNet_recoverAccounts',
params: {
startScanIndex: START_SCAN_INDEX,
maxScanned: MAX_SCANNED,
maxMissed: MAX_MISSED,
chainId,
},
},
},
});
return scannedAccounts;
};
86 changes: 86 additions & 0 deletions wallets/provider-starknet-snap/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import type {
CanEagerConnect,
CanSwitchNetwork,
Connect,
ProviderConnectResult,
Subscribe,
WalletInfo,
} from '@rango-dev/wallets-shared';
import type { BlockchainMeta, SignerFactory } from 'rango-types';

import {
canEagerlyConnectToEvm,
subscribeToEvm,
WalletTypes,
} from '@rango-dev/wallets-shared';
import { starknetBlockchain } from 'rango-types';

import {
getAccounts,
installStarknetSnap,
isStarknetSnapInstalled,
metamask as metamask_instance,
} from './helpers';
import signer from './signer';

const WALLET = WalletTypes.STARKNET_SNAP;

export const config = {
type: WALLET,
};

export const getInstance = metamask_instance;
export const connect: Connect = async ({ instance, meta }) => {
/*
* cosmos snap (It's optional)
* If the user approves to install Snap, we take the Cosmos addresses and add them to the accounts.
*/
await installStarknetSnap(instance);
const installed = await isStarknetSnapInstalled(instance);
let accounts: ProviderConnectResult[] = [];
if (installed) {
for (const item of meta) {
const addresses = await getAccounts(instance, item.chainId || '');
console.log({ addresses });

accounts = [
...accounts,
...addresses.map((item) => ({
accounts: [item.address],
chainId: item.chainId,
})),
];
}
}
return accounts;
};

export const subscribe: Subscribe = subscribeToEvm;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably don't need this.


export const canSwitchNetworkTo: CanSwitchNetwork = () => false;

export const getSigners: (provider: any) => SignerFactory = signer;

export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check if we need this.


export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (
allBlockChains
) => {
const starknet = starknetBlockchain(allBlockChains);
return {
name: 'Starknet Snap',
img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/metamask/icon.svg',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need another icon from design team.

installLink: {
CHROME:
'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en',
BRAVE:
'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en',

FIREFOX: 'https://addons.mozilla.org/en-US/firefox/addon/ether-metamask',
EDGE: 'https://microsoftedge.microsoft.com/addons/detail/metamask/ejbalbakoplchlghecdalmeeeajnimhm?hl=en-US',
DEFAULT: 'https://metamask.io/download/',
},
color: '#dac7ae',
supportedChains: starknet,
};
};
11 changes: 11 additions & 0 deletions wallets/provider-starknet-snap/src/signer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { SignerFactory } from 'rango-types';

import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types';

import StarknetSigner from './signers/starknet';

export default function getSigners(provider: any): SignerFactory {
const signers = new DefaultSignerFactory();
signers.registerSigner(TxType.STARKNET, new StarknetSigner(provider));
return signers;
}
36 changes: 36 additions & 0 deletions wallets/provider-starknet-snap/src/signers/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { DEFAULT_SNAP_ID } from '../helpers';

export async function sendTransaction(
provider: any,
contractAddress: string,
contractFuncName: string,
contractCallData: string,
senderAddress: string,
chainId: string | null,
maxFee?: string
) {
try {
const response = await provider.request({
method: 'wallet_invokeSnap',
params: {
snapId: DEFAULT_SNAP_ID,
request: {
method: 'starkNet_sendTransaction',
params: {
contractAddress,
contractFuncName,
contractCallData,
senderAddress,
maxFee,
chainId,
},
},
},
});
return response;
} catch (err) {
//eslint-disable-next-line no-console
console.error(err);
throw err;
}
}
51 changes: 51 additions & 0 deletions wallets/provider-starknet-snap/src/signers/starknet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { GenericSigner, StarknetTransaction } from 'rango-types';

import { SignerError, SignerErrorCode } from 'rango-types';

import { sendTransaction } from './helpers';

class StarknetSigner implements GenericSigner<StarknetTransaction> {
private provider: any;

constructor(provider: any) {
this.provider = provider;
}

public async signMessage(): Promise<string> {
throw SignerError.UnimplementedError('signMessage');
}

async signAndSendTx(
tx: StarknetTransaction,
address: string,
chainId: string | null
): Promise<{ hash: string }> {
const { calls } = tx;

try {
for (const call of calls) {
const res = await sendTransaction(
this.provider,
call.contractAddress,
call.entrypoint,
(call.calldata as string[]).toString(),
address,
chainId
);
console.log({ res });
}

return { hash: '' };
} catch (err) {
console.log({ err });

if (SignerError.isSignerError(err)) {
throw err;
} else {
throw new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, err);
}
}
}
Comment on lines +25 to +48
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to update this code to handle multiple calls once we have access to starkNet_executeTxn.
Consensys/starknet-snap#181

}

export default StarknetSigner;
Loading