@xlabs-libs/wallet-aggregator-near
Advanced tools
Comparing version 0.0.1-alpha.3 to 0.0.1-alpha.4
@@ -18,2 +18,4 @@ "use strict"; | ||
__exportStar(require("./near"), exports); | ||
__exportStar(require("./modalSelector"), exports); | ||
__exportStar(require("./wrapped"), exports); | ||
//# sourceMappingURL=index.js.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.NearWallet = void 0; | ||
const core_1 = require("@near-wallet-selector/core"); | ||
const modal_ui_1 = require("@near-wallet-selector/modal-ui"); | ||
const wallet_aggregator_core_1 = require("@xlabs-libs/wallet-aggregator-core"); | ||
const near_api_js_1 = require("near-api-js"); | ||
const bn_js_1 = require("bn.js"); | ||
class NearWallet extends wallet_aggregator_core_1.Wallet { | ||
constructor({ config, modules, contractId, allowRedirect }) { | ||
super(); | ||
this.accounts = []; | ||
this.onNetworkChange = ({ networkId }) => { | ||
this.network = Object.assign(Object.assign({}, this.network), { networkId }); | ||
this.emit('networkChanged'); | ||
}; | ||
this.config = config; | ||
this.modules = modules; | ||
this.contractId = contractId; | ||
this.allowRedirect = allowRedirect !== null && allowRedirect !== void 0 ? allowRedirect : true; | ||
signMessage() { | ||
throw new wallet_aggregator_core_1.NotSupported(); | ||
} | ||
getAddress() { | ||
var _a; | ||
return (_a = this.activeAccount) === null || _a === void 0 ? void 0 : _a.accountId; | ||
} | ||
getAddresses() { | ||
if (!this.selector) | ||
return []; | ||
return this.accounts.map(a => a.accountId); | ||
} | ||
setMainAddress(id) { | ||
const account = this.accounts.find(acc => acc.accountId === id); | ||
if (!account) { | ||
throw new Error('Account not found/enabled'); | ||
} | ||
this.selector.setActiveAccount(id); | ||
this.activeAccount = account; | ||
} | ||
getNetworkInfo() { | ||
return this.network; | ||
} | ||
getName() { | ||
if (!this.metadata) | ||
return 'Near'; | ||
return this.metadata.name; | ||
} | ||
getUrl() { | ||
return 'https://near.org'; | ||
} | ||
getIcon() { | ||
if (!this.metadata) | ||
return ''; | ||
return this.metadata.iconUrl; | ||
} | ||
getChainId() { | ||
return wallet_aggregator_core_1.CHAIN_ID_NEAR; | ||
} | ||
getBalance() { | ||
throw new wallet_aggregator_core_1.NotSupported(); | ||
} | ||
signTransaction(tx) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const wallet = yield this.getWallet(); | ||
if (!wallet) | ||
throw new Error('Not connected'); | ||
return tx; | ||
}); | ||
} | ||
sendTransaction(txs) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const wallet = yield this.getWallet(); | ||
if (!wallet || !this.activeAccount) | ||
throw new Error('Not connected'); | ||
let result; | ||
if (wallet.type === 'browser') { | ||
const connection = yield (0, near_api_js_1.connect)(this.config); | ||
const account = yield connection.account(this.activeAccount.accountId); | ||
result = []; | ||
for (const tx of txs.transactions) { | ||
// browser wallets may redirect to another page, which might not be desirable for developers | ||
if (this.allowRedirect) { | ||
for (const tx of txs.transactions) { | ||
const outcome = yield wallet.signAndSendTransaction(tx); | ||
result.push(outcome); | ||
} | ||
} | ||
else { | ||
for (const action of tx.actions) { | ||
result.push(yield this.executeAction(account, action)); | ||
} | ||
} | ||
} | ||
} | ||
else { | ||
result = yield wallet.signAndSendTransactions(txs); | ||
} | ||
return { | ||
id: result[result.length - 1].transaction_outcome.id, | ||
data: result | ||
}; | ||
}); | ||
} | ||
executeAction(account, action) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
switch (action.type) { | ||
case "FunctionCall": | ||
return account.functionCall({ | ||
args: action.params.args, | ||
methodName: action.params.methodName, | ||
gas: new bn_js_1.BN(action.params.gas || 0), | ||
attachedDeposit: new bn_js_1.BN(action.params.deposit || 0), | ||
contractId: this.contractId | ||
}); | ||
default: | ||
throw new Error('WIP: only FunctionCall is supported for browser wallets'); | ||
} | ||
}); | ||
} | ||
signMessage(msg) { | ||
throw new wallet_aggregator_core_1.NotSupported(); | ||
} | ||
/** | ||
* TODO: this is using a modal library. Find a way to programatically select a wallet, maybe by receiving | ||
* the type through constructor or as an argument for connect() | ||
*/ | ||
connect() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.selector = yield (0, core_1.setupWalletSelector)({ | ||
network: this.config.networkId, | ||
modules: this.modules | ||
}); | ||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { | ||
const modal = yield (0, modal_ui_1.setupModal)(this.selector, { | ||
contractId: this.contractId, | ||
onHide: (reason) => { | ||
if (reason === 'user-triggered') { | ||
reject('Connect cancelled'); | ||
} | ||
} | ||
}); | ||
modal.show(); | ||
const onSignIn = ({ accounts }) => __awaiter(this, void 0, void 0, function* () { | ||
yield onConnect(accounts); | ||
}); | ||
const onConnect = (accounts) => __awaiter(this, void 0, void 0, function* () { | ||
var _a, _b; | ||
modal.hide(); | ||
const wallet = yield this.selector.wallet(); | ||
this.accounts = accounts; | ||
this.activeAccount = accounts[0]; | ||
this.metadata = wallet === null || wallet === void 0 ? void 0 : wallet.metadata; | ||
this.network = Object.assign({}, this.selector.options.network); | ||
(_a = this.selector) === null || _a === void 0 ? void 0 : _a.on('networkChanged', this.onNetworkChange); | ||
(_b = this.selector) === null || _b === void 0 ? void 0 : _b.off('signedIn', onSignIn); | ||
resolve(this.getAddresses()); | ||
}); | ||
this.selector.on('signedIn', onSignIn); | ||
const accounts = this.selector.store.getState().accounts; | ||
if (accounts.length > 0) { | ||
onConnect(accounts); | ||
} | ||
})); | ||
}); | ||
} | ||
isConnected() { | ||
var _a; | ||
return !!((_a = this.selector) === null || _a === void 0 ? void 0 : _a.isSignedIn()); | ||
} | ||
disconnect() { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const wallet = yield this.getWallet(); | ||
if (!wallet) { | ||
throw new Error('Not connected'); | ||
} | ||
this.accounts = []; | ||
this.activeAccount = undefined; | ||
this.metadata = undefined; | ||
yield wallet.signOut(); | ||
(_a = this.selector) === null || _a === void 0 ? void 0 : _a.off('networkChanged', this.onNetworkChange); | ||
this.selector = undefined; | ||
}); | ||
} | ||
/** Returns the active/internal wallet */ | ||
getWallet() { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return (_a = this.selector) === null || _a === void 0 ? void 0 : _a.wallet(); | ||
}); | ||
} | ||
} | ||
exports.NearWallet = NearWallet; | ||
//# sourceMappingURL=near.js.map |
@@ -1,2 +0,4 @@ | ||
export * from './near'; | ||
export * from "./near"; | ||
export * from "./modalSelector"; | ||
export * from "./wrapped"; | ||
//# sourceMappingURL=index.js.map |
@@ -1,177 +0,10 @@ | ||
import { setupWalletSelector } from "@near-wallet-selector/core"; | ||
import { setupModal } from "@near-wallet-selector/modal-ui"; | ||
import { CHAIN_ID_NEAR, NotSupported, Wallet } from "@xlabs-libs/wallet-aggregator-core"; | ||
import { connect } from "near-api-js"; | ||
import { BN } from "bn.js"; | ||
export class NearWallet extends Wallet { | ||
constructor({ config, modules, contractId, allowRedirect }) { | ||
super(); | ||
this.accounts = []; | ||
this.onNetworkChange = ({ networkId }) => { | ||
this.network = { | ||
...this.network, | ||
networkId | ||
}; | ||
this.emit('networkChanged'); | ||
}; | ||
this.config = config; | ||
this.modules = modules; | ||
this.contractId = contractId; | ||
this.allowRedirect = allowRedirect ?? true; | ||
signMessage() { | ||
throw new NotSupported(); | ||
} | ||
getAddress() { | ||
return this.activeAccount?.accountId; | ||
} | ||
getAddresses() { | ||
if (!this.selector) | ||
return []; | ||
return this.accounts.map(a => a.accountId); | ||
} | ||
setMainAddress(id) { | ||
const account = this.accounts.find(acc => acc.accountId === id); | ||
if (!account) { | ||
throw new Error('Account not found/enabled'); | ||
} | ||
this.selector.setActiveAccount(id); | ||
this.activeAccount = account; | ||
} | ||
getNetworkInfo() { | ||
return this.network; | ||
} | ||
getName() { | ||
if (!this.metadata) | ||
return 'Near'; | ||
return this.metadata.name; | ||
} | ||
getUrl() { | ||
return 'https://near.org'; | ||
} | ||
getIcon() { | ||
if (!this.metadata) | ||
return ''; | ||
return this.metadata.iconUrl; | ||
} | ||
getChainId() { | ||
return CHAIN_ID_NEAR; | ||
} | ||
getBalance() { | ||
throw new NotSupported(); | ||
} | ||
async signTransaction(tx) { | ||
const wallet = await this.getWallet(); | ||
if (!wallet) | ||
throw new Error('Not connected'); | ||
return tx; | ||
} | ||
async sendTransaction(txs) { | ||
const wallet = await this.getWallet(); | ||
if (!wallet || !this.activeAccount) | ||
throw new Error('Not connected'); | ||
let result; | ||
if (wallet.type === 'browser') { | ||
const connection = await connect(this.config); | ||
const account = await connection.account(this.activeAccount.accountId); | ||
result = []; | ||
for (const tx of txs.transactions) { | ||
// browser wallets may redirect to another page, which might not be desirable for developers | ||
if (this.allowRedirect) { | ||
for (const tx of txs.transactions) { | ||
const outcome = await wallet.signAndSendTransaction(tx); | ||
result.push(outcome); | ||
} | ||
} | ||
else { | ||
for (const action of tx.actions) { | ||
result.push(await this.executeAction(account, action)); | ||
} | ||
} | ||
} | ||
} | ||
else { | ||
result = await wallet.signAndSendTransactions(txs); | ||
} | ||
return { | ||
id: result[result.length - 1].transaction_outcome.id, | ||
data: result | ||
}; | ||
} | ||
async executeAction(account, action) { | ||
switch (action.type) { | ||
case "FunctionCall": | ||
return account.functionCall({ | ||
args: action.params.args, | ||
methodName: action.params.methodName, | ||
gas: new BN(action.params.gas || 0), | ||
attachedDeposit: new BN(action.params.deposit || 0), | ||
contractId: this.contractId | ||
}); | ||
default: | ||
throw new Error('WIP: only FunctionCall is supported for browser wallets'); | ||
} | ||
} | ||
signMessage(msg) { | ||
throw new NotSupported(); | ||
} | ||
/** | ||
* TODO: this is using a modal library. Find a way to programatically select a wallet, maybe by receiving | ||
* the type through constructor or as an argument for connect() | ||
*/ | ||
async connect() { | ||
this.selector = await setupWalletSelector({ | ||
network: this.config.networkId, | ||
modules: this.modules | ||
}); | ||
return new Promise(async (resolve, reject) => { | ||
const modal = await setupModal(this.selector, { | ||
contractId: this.contractId, | ||
onHide: (reason) => { | ||
if (reason === 'user-triggered') { | ||
reject('Connect cancelled'); | ||
} | ||
} | ||
}); | ||
modal.show(); | ||
const onSignIn = async ({ accounts }) => { | ||
await onConnect(accounts); | ||
}; | ||
const onConnect = async (accounts) => { | ||
modal.hide(); | ||
const wallet = await this.selector.wallet(); | ||
this.accounts = accounts; | ||
this.activeAccount = accounts[0]; | ||
this.metadata = wallet?.metadata; | ||
this.network = { | ||
...this.selector.options.network, | ||
}; | ||
this.selector?.on('networkChanged', this.onNetworkChange); | ||
this.selector?.off('signedIn', onSignIn); | ||
resolve(this.getAddresses()); | ||
}; | ||
this.selector.on('signedIn', onSignIn); | ||
const accounts = this.selector.store.getState().accounts; | ||
if (accounts.length > 0) { | ||
onConnect(accounts); | ||
} | ||
}); | ||
} | ||
isConnected() { | ||
return !!this.selector?.isSignedIn(); | ||
} | ||
async disconnect() { | ||
const wallet = await this.getWallet(); | ||
if (!wallet) { | ||
throw new Error('Not connected'); | ||
} | ||
this.accounts = []; | ||
this.activeAccount = undefined; | ||
this.metadata = undefined; | ||
await wallet.signOut(); | ||
this.selector?.off('networkChanged', this.onNetworkChange); | ||
this.selector = undefined; | ||
} | ||
/** Returns the active/internal wallet */ | ||
async getWallet() { | ||
return this.selector?.wallet(); | ||
} | ||
} | ||
//# sourceMappingURL=near.js.map |
@@ -1,2 +0,4 @@ | ||
export * from './near'; | ||
export * from "./near"; | ||
export * from "./modalSelector"; | ||
export * from "./wrapped"; | ||
//# sourceMappingURL=index.d.ts.map |
import { Action, FinalExecutionOutcome, Network, Wallet as InternalWallet } from "@near-wallet-selector/core"; | ||
import { Address, ChainId, SendTransactionResult, Wallet } from "@xlabs-libs/wallet-aggregator-core"; | ||
import { ConnectConfig as NearConfig } from "near-api-js"; | ||
export interface NearWalletParams { | ||
/** Near configuration */ | ||
config: NearConfig; | ||
/** List of modules/wallets available */ | ||
modules: any[]; | ||
/** Contract ID the wallet/application will interact with */ | ||
contractId: string; | ||
/** Allow browser wallets to redirect to another page */ | ||
allowRedirect?: boolean; | ||
} | ||
interface NearTransaction { | ||
import { ChainId, SendTransactionResult, Wallet } from "@xlabs-libs/wallet-aggregator-core"; | ||
export interface NearTransaction { | ||
signerId?: string; | ||
@@ -19,42 +8,13 @@ receiverId: string; | ||
} | ||
interface NearTransactionParams { | ||
export interface NearTransactionParams { | ||
transactions: NearTransaction[]; | ||
} | ||
type NearTransactionResult = FinalExecutionOutcome[]; | ||
export declare class NearWallet extends Wallet<NearTransactionParams, NearTransactionParams, NearTransactionResult, Network> { | ||
private readonly config; | ||
private readonly modules; | ||
private readonly contractId; | ||
private accounts; | ||
private activeAccount?; | ||
private selector?; | ||
private metadata?; | ||
private allowRedirect; | ||
private network?; | ||
constructor({ config, modules, contractId, allowRedirect }: NearWalletParams); | ||
getAddress(): string | undefined; | ||
getAddresses(): string[]; | ||
setMainAddress(id: string): void; | ||
getNetworkInfo(): Network | undefined; | ||
getName(): string; | ||
getUrl(): string; | ||
getIcon(): string; | ||
export type NearTransactionResult = FinalExecutionOutcome[]; | ||
export declare abstract class NearWallet extends Wallet<NearTransactionParams, NearTransactionParams, NearTransactionResult, Network> { | ||
abstract signTransaction(tx: NearTransactionParams): Promise<NearTransactionParams>; | ||
abstract sendTransaction(txs: NearTransactionParams): Promise<SendTransactionResult<NearTransactionResult>>; | ||
signMessage(): Promise<never>; | ||
abstract getWallet(): Promise<InternalWallet | undefined>; | ||
getChainId(): ChainId; | ||
getBalance(): Promise<string>; | ||
signTransaction(tx: NearTransactionParams): Promise<NearTransactionParams>; | ||
sendTransaction(txs: NearTransactionParams): Promise<SendTransactionResult<NearTransactionResult>>; | ||
private executeAction; | ||
signMessage(msg: any): Promise<any>; | ||
/** | ||
* TODO: this is using a modal library. Find a way to programatically select a wallet, maybe by receiving | ||
* the type through constructor or as an argument for connect() | ||
*/ | ||
connect(): Promise<Address[]>; | ||
isConnected(): boolean; | ||
disconnect(): Promise<void>; | ||
/** Returns the active/internal wallet */ | ||
getWallet(): Promise<InternalWallet | undefined>; | ||
private onNetworkChange; | ||
} | ||
export {}; | ||
//# sourceMappingURL=near.d.ts.map |
{ | ||
"name": "@xlabs-libs/wallet-aggregator-near", | ||
"repository": "https://github.com/XLabs/wallet-aggregator-sdk/tree/master/packages/wallets/near", | ||
"version": "0.0.1-alpha.3", | ||
"version": "0.0.1-alpha.4", | ||
"sideEffects": false, | ||
@@ -26,3 +26,3 @@ "license": "MIT", | ||
"rxjs": "^7.5.7", | ||
"@xlabs-libs/wallet-aggregator-core": "^0.0.1-alpha.7" | ||
"@xlabs-libs/wallet-aggregator-core": "^0.0.1-alpha.10" | ||
}, | ||
@@ -29,0 +29,0 @@ "scripts": { |
@@ -7,6 +7,8 @@ ## Wallet Aggregator - NEAR | ||
Under the hood the wallet uses the `WalletSelector` from `@near-wallet-selector/core`, through the `@near-wallet-selector/modal-ui`. Upon calling `connect`, the wallet will create a modal and prompt the user to login through it. | ||
There are two methods of using this package. You may either use the `NearModalSelectorWallet` class, which under the hood the wallet uses the `@near-wallet-selector/core` and `@near-wallet-selector/modal-ui` packages. Upon calling `connect`, the wallet will create a modal and prompt the user to login through it. On the other hand, you can use the `WrappedNearWallet` which allows programatically interacting with a single wallet; a utility function `wrapWallet` is provided to help create them. | ||
#### Using the NearModalSelectorWallet | ||
```ts | ||
import { NearWallet } from "@xlabs-libs/wallet-aggregator-near"; | ||
import { NearModalSelectorWallet } from "@xlabs-libs/wallet-aggregator-near"; | ||
import { setupDefaultWallets } from "@near-wallet-selector/default-wallets"; | ||
@@ -18,23 +20,53 @@ import { setupMyNearWallet } from "@near-wallet-selector/my-near-wallet"; | ||
const contractId = 'contract.dapp.near'; | ||
const contractId = "contract.dapp.near"; | ||
const config = { | ||
networkId: "mainnet", | ||
keyStore: nearKeyStore, | ||
nodeUrl: "https://rpc.mainnet.near.org", | ||
walletUrl: "https://wallet.mainnet.near.org", | ||
helperUrl: "https://helper.mainnet.near.org", | ||
headers: {}, | ||
} | ||
networkId: "mainnet", | ||
keyStore: nearKeyStore, | ||
nodeUrl: "https://rpc.mainnet.near.org", | ||
walletUrl: "https://wallet.mainnet.near.org", | ||
helperUrl: "https://helper.mainnet.near.org", | ||
headers: {}, | ||
}; | ||
new NearWallet({ | ||
config, | ||
contractId, | ||
modules: [ | ||
...(await setupDefaultWallets()), | ||
setupMyNearWallet(), | ||
setupNightly(), | ||
setupMeteorWallet(), | ||
] | ||
}) | ||
const wallet = new NearModalSelectorWallet({ | ||
config, | ||
contractId, | ||
modules: [ | ||
...(await setupDefaultWallets()), | ||
setupMyNearWallet(), | ||
setupNightly(), | ||
setupMeteorWallet(), | ||
], | ||
}); | ||
await wallet.connect(); | ||
``` | ||
#### Using the WrappedNearWallet | ||
```ts | ||
import { setupMeteorWallet } from "@near-wallet-selector/meteor-wallet"; | ||
import { setupSender } from "@near-wallet-selector/sender"; | ||
import "@near-wallet-selector/modal-ui/styles.css"; | ||
const contractId = "contract.dapp.near"; | ||
const config = { | ||
networkId: "mainnet", | ||
keyStore: nearKeyStore, | ||
nodeUrl: "https://rpc.mainnet.near.org", | ||
walletUrl: "https://wallet.mainnet.near.org", | ||
helperUrl: "https://helper.mainnet.near.org", | ||
headers: {}, | ||
}; | ||
const meteor = await wrapWallet({ | ||
config, | ||
contractId, | ||
factory: setupMeteorWallet(), | ||
}); | ||
const sender = await wrapWallet({ config, contractId, factory: setupSender() }); | ||
await meteor.connect(); | ||
``` |
@@ -1,1 +0,3 @@ | ||
export * from './near'; | ||
export * from "./near"; | ||
export * from "./modalSelector"; | ||
export * from "./wrapped"; |
270
src/near.ts
@@ -1,241 +0,53 @@ | ||
import { Account, Action, FinalExecutionOutcome, Network, NetworkId, setupWalletSelector, Wallet as InternalWallet, WalletMetadata, WalletSelector } from "@near-wallet-selector/core"; | ||
import { setupModal } from "@near-wallet-selector/modal-ui"; | ||
import { Address, ChainId, CHAIN_ID_NEAR, NotSupported, SendTransactionResult, Wallet } from "@xlabs-libs/wallet-aggregator-core"; | ||
import { connect, ConnectConfig as NearConfig, Account as ConnectedAccount } from "near-api-js"; | ||
import { BN } from "bn.js"; | ||
import { | ||
Action, | ||
FinalExecutionOutcome, | ||
Network, | ||
Wallet as InternalWallet, | ||
} from "@near-wallet-selector/core"; | ||
import { | ||
ChainId, | ||
CHAIN_ID_NEAR, | ||
NotSupported, | ||
SendTransactionResult, | ||
Wallet, | ||
} from "@xlabs-libs/wallet-aggregator-core"; | ||
export interface NearWalletParams { | ||
/** Near configuration */ | ||
config: NearConfig; | ||
/** List of modules/wallets available */ | ||
modules: any[]; | ||
/** Contract ID the wallet/application will interact with */ | ||
contractId: string; | ||
/** Allow browser wallets to redirect to another page */ | ||
allowRedirect?: boolean; | ||
export interface NearTransaction { | ||
signerId?: string; | ||
receiverId: string; | ||
actions: Action[]; | ||
} | ||
interface NearTransaction { | ||
signerId?: string; | ||
receiverId: string; | ||
actions: Action[]; | ||
export interface NearTransactionParams { | ||
transactions: NearTransaction[]; | ||
} | ||
interface NearTransactionParams { | ||
transactions: NearTransaction[]; | ||
} | ||
export type NearTransactionResult = FinalExecutionOutcome[]; | ||
type NearTransactionResult = FinalExecutionOutcome[]; | ||
export class NearWallet extends Wallet< | ||
NearTransactionParams, | ||
NearTransactionParams, | ||
NearTransactionResult, | ||
Network | ||
export abstract class NearWallet extends Wallet< | ||
NearTransactionParams, | ||
NearTransactionParams, | ||
NearTransactionResult, | ||
Network | ||
> { | ||
private readonly config: NearConfig; | ||
private readonly modules: any[]; | ||
private readonly contractId: string; | ||
private accounts: Account[] = []; | ||
private activeAccount?: Account; | ||
private selector?: WalletSelector; | ||
private metadata?: WalletMetadata; | ||
private allowRedirect: boolean; | ||
private network?: Network; | ||
abstract signTransaction( | ||
tx: NearTransactionParams | ||
): Promise<NearTransactionParams>; | ||
constructor({ config, modules, contractId, allowRedirect }: NearWalletParams) { | ||
super(); | ||
this.config = config; | ||
this.modules = modules; | ||
this.contractId = contractId; | ||
this.allowRedirect = allowRedirect ?? true; | ||
} | ||
abstract sendTransaction( | ||
txs: NearTransactionParams | ||
): Promise<SendTransactionResult<NearTransactionResult>>; | ||
getAddress(): string | undefined { | ||
return this.activeAccount?.accountId; | ||
} | ||
signMessage(): Promise<never> { | ||
throw new NotSupported(); | ||
} | ||
getAddresses(): string[] { | ||
if (!this.selector) return []; | ||
/** | ||
* Returns the underlying wallet instance, if any | ||
*/ | ||
abstract getWallet(): Promise<InternalWallet | undefined>; | ||
return this.accounts.map(a => a.accountId); | ||
} | ||
setMainAddress(id: string): void { | ||
const account = this.accounts.find(acc => acc.accountId === id); | ||
if (!account) { | ||
throw new Error('Account not found/enabled'); | ||
} | ||
this.selector!.setActiveAccount(id); | ||
this.activeAccount = account; | ||
} | ||
getNetworkInfo(): Network | undefined { | ||
return this.network; | ||
} | ||
getName(): string { | ||
if (!this.metadata) return 'Near'; | ||
return this.metadata.name; | ||
} | ||
getUrl(): string { | ||
return 'https://near.org'; | ||
} | ||
getIcon(): string { | ||
if (!this.metadata) return ''; | ||
return this.metadata.iconUrl; | ||
} | ||
getChainId(): ChainId { | ||
return CHAIN_ID_NEAR; | ||
} | ||
getBalance(): Promise<string> { | ||
throw new NotSupported(); | ||
} | ||
async signTransaction(tx: NearTransactionParams): Promise<NearTransactionParams> { | ||
const wallet = await this.getWallet(); | ||
if (!wallet) throw new Error('Not connected'); | ||
return tx; | ||
} | ||
async sendTransaction(txs: NearTransactionParams): Promise<SendTransactionResult<NearTransactionResult>> { | ||
const wallet = await this.getWallet(); | ||
if (!wallet || !this.activeAccount) throw new Error('Not connected'); | ||
let result: FinalExecutionOutcome[]; | ||
if (wallet.type === 'browser') { | ||
const connection = await connect(this.config); | ||
const account = await connection.account(this.activeAccount.accountId) | ||
result = []; | ||
for (const tx of txs.transactions) { | ||
// browser wallets may redirect to another page, which might not be desirable for developers | ||
if (this.allowRedirect) { | ||
for (const tx of txs.transactions) { | ||
const outcome = await wallet.signAndSendTransaction(tx); | ||
result.push(outcome as FinalExecutionOutcome); | ||
} | ||
} else { | ||
for (const action of tx.actions) { | ||
result.push(await this.executeAction(account, action)); | ||
} | ||
} | ||
} | ||
} else { | ||
result = await wallet.signAndSendTransactions(txs); | ||
} | ||
return { | ||
id: result[result.length - 1].transaction_outcome.id, | ||
data: result | ||
} | ||
} | ||
private async executeAction(account: ConnectedAccount, action: Action): Promise<FinalExecutionOutcome> { | ||
switch (action.type) { | ||
case "FunctionCall": | ||
return account.functionCall({ | ||
args: action.params.args, | ||
methodName: action.params.methodName, | ||
gas: new BN(action.params.gas || 0), | ||
attachedDeposit: new BN(action.params.deposit || 0), | ||
contractId: this.contractId | ||
}); | ||
default: | ||
throw new Error('WIP: only FunctionCall is supported for browser wallets'); | ||
} | ||
} | ||
signMessage(msg: any): Promise<any> { | ||
throw new NotSupported(); | ||
} | ||
/** | ||
* TODO: this is using a modal library. Find a way to programatically select a wallet, maybe by receiving | ||
* the type through constructor or as an argument for connect() | ||
*/ | ||
async connect(): Promise<Address[]> { | ||
this.selector = await setupWalletSelector({ | ||
network: this.config.networkId as NetworkId, | ||
modules: this.modules | ||
}); | ||
return new Promise(async (resolve, reject) => { | ||
const modal = await setupModal(this.selector!, { | ||
contractId: this.contractId, | ||
onHide: (reason) => { | ||
if (reason === 'user-triggered') { | ||
reject('Connect cancelled'); | ||
} | ||
} | ||
}); | ||
modal.show(); | ||
const onSignIn = async ({ accounts }: { accounts: Account[] }) => { | ||
await onConnect(accounts); | ||
} | ||
const onConnect = async (accounts: Account[]) => { | ||
modal.hide(); | ||
const wallet = await this.selector!.wallet(); | ||
this.accounts = accounts; | ||
this.activeAccount = accounts[0]; | ||
this.metadata = wallet?.metadata; | ||
this.network = { | ||
...this.selector!.options.network, | ||
} | ||
this.selector?.on('networkChanged', this.onNetworkChange); | ||
this.selector?.off('signedIn', onSignIn); | ||
resolve(this.getAddresses()); | ||
}; | ||
this.selector!.on('signedIn', onSignIn); | ||
const accounts = this.selector!.store.getState().accounts; | ||
if (accounts.length > 0) { | ||
onConnect(accounts); | ||
} | ||
}); | ||
} | ||
isConnected(): boolean { | ||
return !!this.selector?.isSignedIn(); | ||
} | ||
async disconnect(): Promise<void> { | ||
const wallet = await this.getWallet(); | ||
if (!wallet) { | ||
throw new Error('Not connected') | ||
} | ||
this.accounts = []; | ||
this.activeAccount = undefined; | ||
this.metadata = undefined; | ||
await wallet.signOut(); | ||
this.selector?.off('networkChanged', this.onNetworkChange); | ||
this.selector = undefined; | ||
} | ||
/** Returns the active/internal wallet */ | ||
async getWallet(): Promise<InternalWallet | undefined> { | ||
return this.selector?.wallet(); | ||
} | ||
private onNetworkChange = ({ networkId }: { networkId: string; }) => { | ||
this.network = { | ||
...this.network!, | ||
networkId | ||
} | ||
this.emit('networkChanged'); | ||
}; | ||
getChainId(): ChainId { | ||
return CHAIN_ID_NEAR; | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
79745
30
1403
71
3