Socket
Socket
Sign inDemoInstall

near-api-js

Package Overview
Dependencies
Maintainers
7
Versions
77
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

near-api-js - npm Package Compare versions

Comparing version 0.44.2 to 0.45.0

LICENSE-APACHE

39

lib/account_multisig.d.ts

@@ -15,2 +15,20 @@ import BN from 'bn.js';

declare type verifyCodeFunction = (securityCode: any) => Promise<any>;
export declare enum MultisigDeleteRequestRejectionError {
CANNOT_DESERIALIZE_STATE = "Cannot deserialize the contract state",
MULTISIG_NOT_INITIALIZED = "Smart contract panicked: Multisig contract should be initialized before usage",
NO_SUCH_REQUEST = "Smart contract panicked: panicked at 'No such request: either wrong number or already confirmed'",
REQUEST_COOLDOWN_ERROR = "Request cannot be deleted immediately after creation.",
METHOD_NOT_FOUND = "Contract method is not found"
}
export declare enum MultisigStateStatus {
INVALID_STATE = 0,
STATE_NOT_INITIALIZED = 1,
VALID_STATE = 2,
UNKNOWN_STATE = 3
}
declare enum MultisigCodeStatus {
INVALID_CODE = 0,
VALID_CODE = 1,
UNKNOWN_CODE = 2
}
export declare class AccountMultisig extends Account {

@@ -23,4 +41,10 @@ storage: any;

private _signAndSendTransaction;
checkMultisigCodeAndStateStatus(contractBytes?: Uint8Array): Promise<{
codeStatus: MultisigCodeStatus;
stateStatus: MultisigStateStatus;
}>;
deleteRequest(request_id: any): Promise<FinalExecutionOutcome>;
deleteAllRequests(): Promise<void>;
deleteUnconfirmedRequests(): Promise<void>;
getRequestIds(): Promise<string>;
getRequestIds(): Promise<string[]>;
getRequest(): any;

@@ -58,3 +82,14 @@ setRequest(data: any): any;

deployMultisig(contractBytes: Uint8Array): Promise<FinalExecutionOutcome>;
disable(contractBytes: Uint8Array): Promise<FinalExecutionOutcome>;
disableWithFAK({ contractBytes, cleanupContractBytes }: {
contractBytes: Uint8Array;
cleanupContractBytes?: Uint8Array;
}): Promise<FinalExecutionOutcome>;
get2faDisableCleanupActions(cleanupContractBytes: Uint8Array): Promise<Action[]>;
get2faDisableKeyConversionActions(): Promise<Action[]>;
/**
* This method converts LAKs back to FAKs, clears state and deploys an 'empty' contract (contractBytes param)
* @param [contractBytes]{@link https://github.com/near/near-wallet/blob/master/packages/frontend/src/wasm/main.wasm?raw=true}
* @param [cleanupContractBytes]{@link https://github.com/near/core-contracts/blob/master/state-cleanup/res/state_cleanup.wasm?raw=true}
*/
disable(contractBytes: Uint8Array, cleanupContractBytes: Uint8Array): Promise<FinalExecutionOutcome>;
sendCodeDefault(): Promise<any>;

@@ -61,0 +96,0 @@ getCodeDefault(method: any): Promise<string>;

@@ -6,3 +6,3 @@ 'use strict';

Object.defineProperty(exports, "__esModule", { value: true });
exports.Account2FA = exports.AccountMultisig = exports.MULTISIG_CONFIRM_METHODS = exports.MULTISIG_CHANGE_METHODS = exports.MULTISIG_DEPOSIT = exports.MULTISIG_GAS = exports.MULTISIG_ALLOWANCE = exports.MULTISIG_STORAGE_KEY = void 0;
exports.Account2FA = exports.AccountMultisig = exports.MultisigStateStatus = exports.MultisigDeleteRequestRejectionError = exports.MULTISIG_CONFIRM_METHODS = exports.MULTISIG_CHANGE_METHODS = exports.MULTISIG_DEPOSIT = exports.MULTISIG_GAS = exports.MULTISIG_ALLOWANCE = exports.MULTISIG_STORAGE_KEY = void 0;
const bn_js_1 = __importDefault(require("bn.js"));

@@ -14,2 +14,3 @@ const depd_1 = __importDefault(require("depd"));

const transaction_1 = require("./transaction");
const providers_1 = require("./providers");
const web_1 = require("./utils/web");

@@ -23,2 +24,24 @@ exports.MULTISIG_STORAGE_KEY = '__multisigRequest';

exports.MULTISIG_CONFIRM_METHODS = ['confirm'];
var MultisigDeleteRequestRejectionError;
(function (MultisigDeleteRequestRejectionError) {
MultisigDeleteRequestRejectionError["CANNOT_DESERIALIZE_STATE"] = "Cannot deserialize the contract state";
MultisigDeleteRequestRejectionError["MULTISIG_NOT_INITIALIZED"] = "Smart contract panicked: Multisig contract should be initialized before usage";
MultisigDeleteRequestRejectionError["NO_SUCH_REQUEST"] = "Smart contract panicked: panicked at 'No such request: either wrong number or already confirmed'";
MultisigDeleteRequestRejectionError["REQUEST_COOLDOWN_ERROR"] = "Request cannot be deleted immediately after creation.";
MultisigDeleteRequestRejectionError["METHOD_NOT_FOUND"] = "Contract method is not found";
})(MultisigDeleteRequestRejectionError = exports.MultisigDeleteRequestRejectionError || (exports.MultisigDeleteRequestRejectionError = {}));
;
var MultisigStateStatus;
(function (MultisigStateStatus) {
MultisigStateStatus[MultisigStateStatus["INVALID_STATE"] = 0] = "INVALID_STATE";
MultisigStateStatus[MultisigStateStatus["STATE_NOT_INITIALIZED"] = 1] = "STATE_NOT_INITIALIZED";
MultisigStateStatus[MultisigStateStatus["VALID_STATE"] = 2] = "VALID_STATE";
MultisigStateStatus[MultisigStateStatus["UNKNOWN_STATE"] = 3] = "UNKNOWN_STATE";
})(MultisigStateStatus = exports.MultisigStateStatus || (exports.MultisigStateStatus = {}));
var MultisigCodeStatus;
(function (MultisigCodeStatus) {
MultisigCodeStatus[MultisigCodeStatus["INVALID_CODE"] = 0] = "INVALID_CODE";
MultisigCodeStatus[MultisigCodeStatus["VALID_CODE"] = 1] = "VALID_CODE";
MultisigCodeStatus[MultisigCodeStatus["UNKNOWN_CODE"] = 2] = "UNKNOWN_CODE";
})(MultisigCodeStatus || (MultisigCodeStatus = {}));
// in memory request cache for node w/o localStorage

@@ -87,2 +110,53 @@ const storageFallback = {

}
/*
* This method submits a canary transaction that is expected to always fail in order to determine whether the contract currently has valid multisig state
* and whether it is initialized. The canary transaction attempts to delete a request at index u32_max and will go through if a request exists at that index.
* a u32_max + 1 and -1 value cannot be used for the canary due to expected u32 error thrown before deserialization attempt.
*/
async checkMultisigCodeAndStateStatus(contractBytes) {
const u32_max = 4294967295;
const validCodeStatusIfNoDeploy = contractBytes ? MultisigCodeStatus.UNKNOWN_CODE : MultisigCodeStatus.VALID_CODE;
try {
if (contractBytes) {
await super.signAndSendTransaction({
receiverId: this.accountId, actions: [
transaction_1.deployContract(contractBytes),
transaction_1.functionCall('delete_request', { request_id: u32_max }, exports.MULTISIG_GAS, exports.MULTISIG_DEPOSIT)
]
});
}
else {
await this.deleteRequest(u32_max);
}
return { codeStatus: MultisigCodeStatus.VALID_CODE, stateStatus: MultisigStateStatus.VALID_STATE };
}
catch (e) {
if (new RegExp(MultisigDeleteRequestRejectionError.CANNOT_DESERIALIZE_STATE).test(e && e.kind && e.kind.ExecutionError)) {
return { codeStatus: validCodeStatusIfNoDeploy, stateStatus: MultisigStateStatus.INVALID_STATE };
}
else if (new RegExp(MultisigDeleteRequestRejectionError.MULTISIG_NOT_INITIALIZED).test(e && e.kind && e.kind.ExecutionError)) {
return { codeStatus: validCodeStatusIfNoDeploy, stateStatus: MultisigStateStatus.STATE_NOT_INITIALIZED };
}
else if (new RegExp(MultisigDeleteRequestRejectionError.NO_SUCH_REQUEST).test(e && e.kind && e.kind.ExecutionError)) {
return { codeStatus: validCodeStatusIfNoDeploy, stateStatus: MultisigStateStatus.VALID_STATE };
}
else if (new RegExp(MultisigDeleteRequestRejectionError.METHOD_NOT_FOUND).test(e && e.message)) {
// not reachable if transaction included a deploy
return { codeStatus: MultisigCodeStatus.INVALID_CODE, stateStatus: MultisigStateStatus.UNKNOWN_STATE };
}
throw e;
}
}
deleteRequest(request_id) {
return super.signAndSendTransaction({
receiverId: this.accountId,
actions: [transaction_1.functionCall('delete_request', { request_id }, exports.MULTISIG_GAS, exports.MULTISIG_DEPOSIT)]
});
}
async deleteAllRequests() {
const request_ids = await this.getRequestIds();
if (request_ids.length) {
await Promise.all(request_ids.map((id) => this.deleteRequest(id)));
}
}
async deleteUnconfirmedRequests() {

@@ -177,9 +251,51 @@ // TODO: Delete in batch, don't delete unexpired

];
if ((await this.state()).code_hash === '11111111111111111111111111111111') {
actions.push(transaction_1.functionCall('new', newArgs, exports.MULTISIG_GAS, exports.MULTISIG_DEPOSIT));
const newFunctionCallActionBatch = actions.concat(transaction_1.functionCall('new', newArgs, exports.MULTISIG_GAS, exports.MULTISIG_DEPOSIT));
console.log('deploying multisig contract for', accountId);
const { stateStatus: multisigStateStatus } = await this.checkMultisigCodeAndStateStatus(contractBytes);
switch (multisigStateStatus) {
case MultisigStateStatus.STATE_NOT_INITIALIZED:
return await super.signAndSendTransactionWithAccount(accountId, newFunctionCallActionBatch);
case MultisigStateStatus.VALID_STATE:
return await super.signAndSendTransactionWithAccount(accountId, actions);
case MultisigStateStatus.INVALID_STATE:
throw new providers_1.TypedError(`Can not deploy a contract to account ${this.accountId} on network ${this.connection.networkId}, the account has existing state.`, 'ContractHasExistingState');
default:
throw new providers_1.TypedError(`Can not deploy a contract to account ${this.accountId} on network ${this.connection.networkId}, the account state could not be verified.`, 'ContractStateUnknown');
}
console.log('deploying multisig contract for', accountId);
return await super.signAndSendTransactionWithAccount(accountId, actions);
}
async disable(contractBytes) {
async disableWithFAK({ contractBytes, cleanupContractBytes }) {
let cleanupActions = [];
if (cleanupContractBytes) {
await this.deleteAllRequests().catch(e => e);
cleanupActions = await this.get2faDisableCleanupActions(cleanupContractBytes);
}
const keyConversionActions = await this.get2faDisableKeyConversionActions();
const actions = [
...cleanupActions,
...keyConversionActions,
transaction_1.deployContract(contractBytes)
];
const accessKeyInfo = await this.findAccessKey(this.accountId, actions);
if (accessKeyInfo && accessKeyInfo.accessKey && accessKeyInfo.accessKey.permission !== 'FullAccess') {
throw new providers_1.TypedError(`No full access key found in keystore. Unable to bypass multisig`, 'NoFAKFound');
}
return this.signAndSendTransactionWithAccount(this.accountId, actions);
}
async get2faDisableCleanupActions(cleanupContractBytes) {
const currentAccountState = await this.viewState('').catch(error => {
const cause = error.cause && error.cause.name;
if (cause == 'NO_CONTRACT_CODE') {
return [];
}
throw cause == 'TOO_LARGE_CONTRACT_STATE'
? new providers_1.TypedError(`Can not deploy a contract to account ${this.accountId} on network ${this.connection.networkId}, the account has existing state.`, 'ContractHasExistingState')
: error;
});
const currentAccountStateKeys = currentAccountState.map(({ key }) => key.toString('base64'));
return currentAccountState.length ? [
transaction_1.deployContract(cleanupContractBytes),
transaction_1.functionCall('clean', { keys: currentAccountStateKeys }, exports.MULTISIG_GAS, new bn_js_1.default('0'))
] : [];
}
async get2faDisableKeyConversionActions() {
const { accountId } = this;

@@ -196,11 +312,34 @@ const accessKeys = await this.getAccessKeys();

const confirmOnlyKey = key_pair_1.PublicKey.from((await this.postSignedJson('/2fa/getAccessKey', { accountId })).publicKey);
const actions = [
return [
transaction_1.deleteKey(confirmOnlyKey),
...lak2fak.map(({ public_key }) => transaction_1.deleteKey(key_pair_1.PublicKey.from(public_key))),
...lak2fak.map(({ public_key }) => transaction_1.addKey(key_pair_1.PublicKey.from(public_key), null)),
...lak2fak.map(({ public_key }) => transaction_1.addKey(key_pair_1.PublicKey.from(public_key), transaction_1.fullAccessKey()))
];
}
/**
* This method converts LAKs back to FAKs, clears state and deploys an 'empty' contract (contractBytes param)
* @param [contractBytes]{@link https://github.com/near/near-wallet/blob/master/packages/frontend/src/wasm/main.wasm?raw=true}
* @param [cleanupContractBytes]{@link https://github.com/near/core-contracts/blob/master/state-cleanup/res/state_cleanup.wasm?raw=true}
*/
async disable(contractBytes, cleanupContractBytes) {
const { stateStatus } = await this.checkMultisigCodeAndStateStatus();
if (stateStatus !== MultisigStateStatus.VALID_STATE && stateStatus !== MultisigStateStatus.STATE_NOT_INITIALIZED) {
throw new providers_1.TypedError(`Can not deploy a contract to account ${this.accountId} on network ${this.connection.networkId}, the account state could not be verified.`, 'ContractStateUnknown');
}
let deleteAllRequestsError;
await this.deleteAllRequests().catch(e => deleteAllRequestsError = e);
const cleanupActions = await this.get2faDisableCleanupActions(cleanupContractBytes).catch(e => {
if (e.type === 'ContractHasExistingState') {
throw deleteAllRequestsError || e;
}
throw e;
});
const actions = [
...cleanupActions,
...(await this.get2faDisableKeyConversionActions()),
transaction_1.deployContract(contractBytes),
];
console.log('disabling 2fa for', accountId);
console.log('disabling 2fa for', this.accountId);
return await this.signAndSendTransaction({
receiverId: accountId,
receiverId: this.accountId,
actions

@@ -207,0 +346,0 @@ });

@@ -68,2 +68,6 @@ /// <reference types="node" />

stringify?: (input: any) => Buffer;
/**
* Is contract from JS SDK, automatically encodes args from JS SDK to binary.
*/
jsContract?: boolean;
}

@@ -70,0 +74,0 @@ declare function parseJsonFromRawResponse(response: Uint8Array): any;

20

lib/account.js

@@ -283,8 +283,20 @@ "use strict";

}
functionCallV2({ contractId, methodName, args = {}, gas = constants_1.DEFAULT_FUNCTION_CALL_GAS, attachedDeposit, walletMeta, walletCallbackUrl, stringify }) {
functionCallV2({ contractId, methodName, args = {}, gas = constants_1.DEFAULT_FUNCTION_CALL_GAS, attachedDeposit, walletMeta, walletCallbackUrl, stringify, jsContract }) {
this.validateArgs(args);
const stringifyArg = stringify === undefined ? transaction_1.stringifyJsonOrBytes : stringify;
let functionCallArgs;
if (jsContract) {
function encodeCall(contractId, method, args) {
return Buffer.concat([Buffer.from(contractId), Buffer.from([0]), Buffer.from(method), Buffer.from([0]), Buffer.from(args)]);
}
const encodedArgs = encodeCall(contractId, methodName, JSON.stringify(Object.values(args)));
functionCallArgs = ['call_js_contract', encodedArgs, gas, attachedDeposit, null, true];
}
else {
const stringifyArg = stringify === undefined ? transaction_1.stringifyJsonOrBytes : stringify;
functionCallArgs = [methodName, args, gas, attachedDeposit, stringifyArg, false];
}
return this.signAndSendTransaction({
receiverId: contractId,
actions: [transaction_1.functionCall(methodName, args, gas, attachedDeposit, stringifyArg)],
receiverId: jsContract ? this.connection.jsvmAccountId : contractId,
// eslint-disable-next-line prefer-spread
actions: [transaction_1.functionCall.apply(void 0, functionCallArgs)],
walletMeta,

@@ -291,0 +303,0 @@ walletCallbackUrl

@@ -10,2 +10,3 @@ import { Provider } from './providers';

readonly signer: Signer;
readonly jsvmAccountId: string;
constructor(networkId: string, provider: Provider, signer: Signer);

@@ -12,0 +13,0 @@ /**

@@ -63,2 +63,6 @@ /**

walletUrl?: string;
/**
* JVSM account ID for NEAR JS SDK
*/
jsvmAccountId?: string;
}

@@ -65,0 +69,0 @@ /**

@@ -34,3 +34,4 @@ "use strict";

provider: { type: 'JsonRpcProvider', args: { url: config.nodeUrl, headers: config.headers } },
signer: config.signer || { type: 'InMemorySigner', keyStore: config.keyStore || config.deps.keyStore }
signer: config.signer || { type: 'InMemorySigner', keyStore: config.keyStore || (config.deps && config.deps.keyStore) },
jsvmAccountId: config.jsvmAccountId || `jsvm.${config.networkId}`
});

@@ -37,0 +38,0 @@ if (config.masterAccount) {

@@ -66,3 +66,3 @@ /// <reference types="node" />

*/
export declare function functionCall(methodName: string, args: Uint8Array | object, gas: BN, deposit: BN, stringify?: typeof stringifyJsonOrBytes): Action;
export declare function functionCall(methodName: string, args: Uint8Array | object, gas: BN, deposit: BN, stringify?: typeof stringifyJsonOrBytes, jsContract?: boolean): Action;
export declare function transfer(deposit: BN): Action;

@@ -69,0 +69,0 @@ export declare function stake(stake: BN, publicKey: PublicKey): Action;

@@ -82,3 +82,6 @@ "use strict";

*/
function functionCall(methodName, args, gas, deposit, stringify = stringifyJsonOrBytes) {
function functionCall(methodName, args, gas, deposit, stringify = stringifyJsonOrBytes, jsContract = false) {
if (jsContract) {
return new Action({ functionCall: new FunctionCall({ methodName, args, gas, deposit }) });
}
return new Action({ functionCall: new FunctionCall({ methodName, args: stringify(args), gas, deposit }) });

@@ -85,0 +88,0 @@ }

{
"name": "near-api-js",
"description": "JavaScript library to interact with NEAR Protocol via RPC API",
"version": "0.44.2",
"version": "0.45.0",
"repository": {

@@ -15,3 +15,3 @@ "type": "git",

"bn.js": "5.2.0",
"borsh": "^0.6.0",
"borsh": "^0.7.0",
"bs58": "^4.0.0",

@@ -66,3 +66,4 @@ "depd": "^2.0.0",

"prefuzz": "yarn build",
"fuzz": "jsfuzz test/fuzz/borsh-roundtrip.js test/fuzz/corpus/"
"fuzz": "jsfuzz test/fuzz/borsh-roundtrip.js test/fuzz/corpus/",
"prepare": "husky install"
},

@@ -69,0 +70,0 @@ "bundlewatch": {

@@ -57,3 +57,3 @@ # near-api-js

1. [Change hash for the commit with errors in the nearcore](https://github.com/near/near-api-js/blob/master/gen_error_types.js#L7-L9)
1. [Change hash for the commit with errors in the nearcore](https://github.com/near/near-api-js/blob/master/fetch_error_schema.js#L8-L9)
2. Fetch new schema: `node fetch_error_schema.js`

@@ -60,0 +60,0 @@ 3. `yarn build` to update `lib/**.js` files

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc