near-api-js
Advanced tools
Comparing version 0.30.0 to 0.31.0
@@ -7,2 +7,3 @@ import BN from 'bn.js'; | ||
import { FinalExecutionOutcome } from './providers'; | ||
export declare const MULTISIG_STORAGE_KEY = "__multisigRequest"; | ||
export declare const MULTISIG_ALLOWANCE: BN; | ||
@@ -23,4 +24,4 @@ export declare const MULTISIG_GAS: BN; | ||
contract: MultisigContract; | ||
pendingRequest: any; | ||
constructor(connection: Connection, accountId: string); | ||
storage: any; | ||
constructor(connection: Connection, accountId: string, storage: any); | ||
addKey(publicKey: string | PublicKey, contractId?: string, methodName?: string, amount?: BN): Promise<FinalExecutionOutcome>; | ||
@@ -35,3 +36,3 @@ signAndSendTransaction(receiverId: string, actions: Action[]): Promise<FinalExecutionOutcome>; | ||
getRequest(): any; | ||
setRequest(data: any): void; | ||
setRequest(data: any): any; | ||
sendRequestCode(): Promise<any>; | ||
@@ -38,0 +39,0 @@ verifyRequestCode(securityCode: string): Promise<any>; |
@@ -6,3 +6,3 @@ 'use strict'; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.AccountMultisig = exports.MULTISIG_CONFIRM_METHODS = exports.MULTISIG_VIEW_METHODS = exports.MULTISIG_CHANGE_METHODS = exports.MULTISIG_DEPOSIT = exports.MULTISIG_GAS = exports.MULTISIG_ALLOWANCE = void 0; | ||
exports.AccountMultisig = exports.MULTISIG_CONFIRM_METHODS = exports.MULTISIG_VIEW_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,4 +14,6 @@ const account_1 = require("./account"); | ||
const transaction_1 = require("./transaction"); | ||
const web_1 = require("./utils/web"); | ||
const NETWORK_ID = process.env.REACT_APP_NETWORK_ID || 'default'; | ||
const CONTRACT_HELPER_URL = process.env.CONTRACT_HELPER_URL || 'https://helper.testnet.near.org'; | ||
exports.MULTISIG_STORAGE_KEY = '__multisigRequest'; | ||
exports.MULTISIG_ALLOWANCE = new bn_js_1.default(process.env.MULTISIG_ALLOWANCE || format_1.parseNearAmount('1')); | ||
@@ -24,5 +26,10 @@ exports.MULTISIG_GAS = new bn_js_1.default(process.env.MULTISIG_GAS || '100000000000000'); | ||
; | ||
// in memory request cache for node w/o localStorage | ||
let storageFallback = { | ||
[exports.MULTISIG_STORAGE_KEY]: null | ||
}; | ||
class AccountMultisig extends account_1.Account { | ||
constructor(connection, accountId) { | ||
constructor(connection, accountId, storage) { | ||
super(connection, accountId); | ||
this.storage = storage; | ||
this.contract = getContract(this); | ||
@@ -87,3 +94,3 @@ } | ||
catch (e) { | ||
console.warn(e); | ||
console.warn("Attempt to delete an earlier request before 15 minutes failed. Will try again."); | ||
} | ||
@@ -103,6 +110,12 @@ } | ||
getRequest() { | ||
return JSON.parse(localStorage.getItem(`__multisigRequest`) || `{}`); | ||
if (this.storage) { | ||
return JSON.parse(this.storage.getItem(exports.MULTISIG_STORAGE_KEY) || `{}`); | ||
} | ||
return storageFallback[exports.MULTISIG_STORAGE_KEY]; | ||
} | ||
setRequest(data) { | ||
localStorage.setItem(`__multisigRequest`, JSON.stringify(data)); | ||
if (this.storage) { | ||
return this.storage.setItem(exports.MULTISIG_STORAGE_KEY, JSON.stringify(data)); | ||
} | ||
storageFallback[exports.MULTISIG_STORAGE_KEY] = data; | ||
} | ||
@@ -162,17 +175,6 @@ // default helpers for CH | ||
async postSignedJson(path, body) { | ||
const response = await fetch(CONTRACT_HELPER_URL + path, { | ||
method: 'POST', | ||
body: JSON.stringify({ | ||
...body, | ||
...(await this.signatureFor()) | ||
}), | ||
headers: { 'Content-type': 'application/json; charset=utf-8' } | ||
}); | ||
if (!response.ok) { | ||
throw new Error(response.status + ': ' + await response.text()); | ||
} | ||
if (response.status === 204) { | ||
return null; | ||
} | ||
return await response.json(); | ||
return await web_1.fetchJson(CONTRACT_HELPER_URL + path, JSON.stringify({ | ||
...body, | ||
...(await this.signatureFor()) | ||
})); | ||
} | ||
@@ -201,3 +203,3 @@ } | ||
amount: (deposit && deposit.toString()) || undefined, | ||
deposit: (deposit && deposit.toString()) || undefined, | ||
deposit: (deposit && deposit.toString()) || '0', | ||
permission: undefined, | ||
@@ -204,0 +206,0 @@ }; |
import BN from 'bn.js'; | ||
import { Action, AccessKey } from './transaction'; | ||
import { AccessKey, Action, SignedTransaction } from './transaction'; | ||
import { FinalExecutionOutcome } from './providers'; | ||
@@ -40,2 +40,3 @@ import { Connection } from './connection'; | ||
private printLogs; | ||
protected signTransaction(receiverId: string, actions: Action[]): Promise<[Uint8Array, SignedTransaction]>; | ||
/** | ||
@@ -42,0 +43,0 @@ * @param receiverId NEAR account receiving the transaction |
@@ -71,2 +71,14 @@ 'use strict'; | ||
} | ||
async signTransaction(receiverId, actions) { | ||
await this.ready; | ||
const accessKeyInfo = await this.findAccessKey(receiverId, actions); | ||
if (!accessKeyInfo) { | ||
throw new providers_1.TypedError(`Can not sign transactions for account ${this.accountId} on network ${this.connection.networkId}, no matching key pair found in ${this.connection.signer}.`, 'KeyNotFound'); | ||
} | ||
const { accessKey } = accessKeyInfo; | ||
const status = await this.connection.provider.status(); | ||
const nonce = ++accessKey.nonce; | ||
// TODO: get latest_block_hash from block query using `final` finality | ||
return await transaction_1.signTransaction(receiverId, nonce, actions, serialize_1.base_decode(status.sync_info.latest_block_hash), this.connection.signer, this.accountId, this.connection.networkId); | ||
} | ||
/** | ||
@@ -82,10 +94,4 @@ * @param receiverId NEAR account receiving the transaction | ||
const result = await exponential_backoff_1.default(TX_STATUS_RETRY_WAIT, TX_NONCE_RETRY_NUMBER, TX_STATUS_RETRY_WAIT_BACKOFF, async () => { | ||
const accessKeyInfo = await this.findAccessKey(receiverId, actions); | ||
if (!accessKeyInfo) { | ||
throw new providers_1.TypedError(`Can not sign transactions for account ${this.accountId} on network ${this.connection.networkId}, no matching key pair found in ${this.connection.signer}.`, 'KeyNotFound'); | ||
} | ||
const { publicKey, accessKey } = accessKeyInfo; | ||
const status = await this.connection.provider.status(); | ||
const nonce = ++accessKey.nonce; | ||
[txHash, signedTx] = await transaction_1.signTransaction(receiverId, nonce, actions, serialize_1.base_decode(status.sync_info.latest_block_hash), this.connection.signer, this.accountId, this.connection.networkId); | ||
[txHash, signedTx] = await this.signTransaction(receiverId, actions); | ||
const publicKey = signedTx.transaction.publicKey; | ||
try { | ||
@@ -92,0 +98,0 @@ const result = await exponential_backoff_1.default(TX_STATUS_RETRY_WAIT, TX_STATUS_RETRY_NUMBER, TX_STATUS_RETRY_WAIT_BACKOFF, async () => { |
@@ -18,2 +18,4 @@ "use strict"; | ||
} | ||
const isUint8Array = (x) => x && x.byteLength !== undefined && x.byteLength === x.length; | ||
const isObject = (x) => Object.prototype.toString.call(x) === '[object Object]'; | ||
/** | ||
@@ -32,3 +34,3 @@ * Defines a smart contract on NEAR including the mutable and non-mutable methods | ||
value: nameFunction(methodName, async (args = {}, ...ignored) => { | ||
if (ignored.length || Object.prototype.toString.call(args) !== '[object Object]') { | ||
if (ignored.length || !(isObject(args) || isUint8Array(args))) { | ||
throw new errors_1.PositionalArgsError(); | ||
@@ -45,3 +47,3 @@ } | ||
value: nameFunction(methodName, async (args = {}, gas, amount, ...ignored) => { | ||
if (ignored.length || Object.prototype.toString.call(args) !== '[object Object]') { | ||
if (ignored.length || !(isObject(args) || isUint8Array(args))) { | ||
throw new errors_1.PositionalArgsError(); | ||
@@ -48,0 +50,0 @@ } |
@@ -20,2 +20,3 @@ import BN from 'bn.js'; | ||
nodeUrl: string; | ||
walletUrl?: string; | ||
}; | ||
@@ -22,0 +23,0 @@ export declare class Near { |
@@ -48,3 +48,3 @@ "use strict"; | ||
const bytes = signedTransaction.encode(); | ||
return this.sendJsonRpc('broadcast_tx_commit', [Buffer.from(bytes).toString('base64')]).then(provider_1.adaptTransactionResult); | ||
return this.sendJsonRpc('broadcast_tx_commit', [Buffer.from(bytes).toString('base64')]); | ||
} | ||
@@ -59,3 +59,3 @@ /** | ||
async txStatus(txHash, accountId) { | ||
return this.sendJsonRpc('tx', [serialize_1.base_encode(txHash), accountId]).then(provider_1.adaptTransactionResult); | ||
return this.sendJsonRpc('tx', [serialize_1.base_encode(txHash), accountId]); | ||
} | ||
@@ -62,0 +62,0 @@ /** |
@@ -209,3 +209,2 @@ import { Network } from '../utils/network'; | ||
export declare function getTransactionLastResult(txResult: FinalExecutionOutcome): any; | ||
export declare function adaptTransactionResult(txResult: any): FinalExecutionOutcome; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.adaptTransactionResult = exports.getTransactionLastResult = exports.Provider = exports.IdType = exports.FinalExecutionStatusBasic = exports.ExecutionStatusBasic = void 0; | ||
exports.getTransactionLastResult = exports.Provider = exports.IdType = exports.FinalExecutionStatusBasic = exports.ExecutionStatusBasic = void 0; | ||
var ExecutionStatusBasic; | ||
@@ -37,14 +37,1 @@ (function (ExecutionStatusBasic) { | ||
exports.getTransactionLastResult = getTransactionLastResult; | ||
function adaptTransactionResult(txResult) { | ||
if ('receipts' in txResult) { | ||
txResult = { | ||
status: txResult.status, | ||
// not available | ||
transaction: null, | ||
transaction_outcome: txResult.transaction, | ||
receipts_outcome: txResult.receipts | ||
}; | ||
} | ||
return txResult; | ||
} | ||
exports.adaptTransactionResult = adaptTransactionResult; |
{ | ||
"name": "near-api-js", | ||
"description": "JavaScript library to interact with NEAR Protocol via RPC API", | ||
"version": "0.30.0", | ||
"version": "0.31.0", | ||
"repository": { | ||
@@ -22,3 +22,3 @@ "type": "git", | ||
"mustache": "^4.0.0", | ||
"node-fetch": "^2.3.0", | ||
"node-fetch": "^2.6.1", | ||
"text-encoding-utf-8": "^1.0.2", | ||
@@ -25,0 +25,0 @@ "tweetnacl": "^1.0.1" |
@@ -8,3 +8,6 @@ # near-api-js | ||
# Documentation | ||
[Read the TypeDoc API ocumentation](https://near.github.io/near-api-js/) | ||
# Contribute to this library | ||
@@ -11,0 +14,0 @@ |
@@ -11,2 +11,3 @@ 'use strict'; | ||
import { FinalExecutionOutcome } from './providers'; | ||
import { fetchJson } from './utils/web'; | ||
@@ -16,2 +17,3 @@ const NETWORK_ID = process.env.REACT_APP_NETWORK_ID || 'default' | ||
export const MULTISIG_STORAGE_KEY = '__multisigRequest' | ||
export const MULTISIG_ALLOWANCE = new BN(process.env.MULTISIG_ALLOWANCE || parseNearAmount('1')); | ||
@@ -24,2 +26,3 @@ export const MULTISIG_GAS = new BN(process.env.MULTISIG_GAS || '100000000000000'); | ||
interface MultisigContract { | ||
@@ -31,8 +34,14 @@ get_request_nonce(): any, | ||
// in memory request cache for node w/o localStorage | ||
let storageFallback = { | ||
[MULTISIG_STORAGE_KEY]: null | ||
} | ||
export class AccountMultisig extends Account { | ||
public contract: MultisigContract; | ||
public pendingRequest: any; | ||
public storage: any; | ||
constructor(connection: Connection, accountId: string) { | ||
constructor(connection: Connection, accountId: string, storage: any) { | ||
super(connection, accountId); | ||
this.storage = storage; | ||
this.contract = <MultisigContract>getContract(this); | ||
@@ -105,3 +114,3 @@ } | ||
} catch(e) { | ||
console.warn(e) | ||
console.warn("Attempt to delete an earlier request before 15 minutes failed. Will try again.") | ||
} | ||
@@ -126,7 +135,13 @@ } | ||
getRequest() { | ||
return JSON.parse(localStorage.getItem(`__multisigRequest`) || `{}`) | ||
if (this.storage) { | ||
return JSON.parse(this.storage.getItem(MULTISIG_STORAGE_KEY) || `{}`) | ||
} | ||
return storageFallback[MULTISIG_STORAGE_KEY] | ||
} | ||
setRequest(data) { | ||
localStorage.setItem(`__multisigRequest`, JSON.stringify(data)) | ||
if (this.storage) { | ||
return this.storage.setItem(MULTISIG_STORAGE_KEY, JSON.stringify(data)) | ||
} | ||
storageFallback[MULTISIG_STORAGE_KEY] = data | ||
} | ||
@@ -192,17 +207,6 @@ | ||
async postSignedJson(path, body) { | ||
const response = await fetch(CONTRACT_HELPER_URL + path, { | ||
method: 'POST', | ||
body: JSON.stringify({ | ||
...body, | ||
...(await this.signatureFor()) | ||
}), | ||
headers: { 'Content-type': 'application/json; charset=utf-8' } | ||
}); | ||
if (!response.ok) { | ||
throw new Error(response.status + ': ' + await response.text()); | ||
} | ||
if (response.status === 204) { | ||
return null; | ||
} | ||
return await response.json(); | ||
return await fetchJson(CONTRACT_HELPER_URL + path, JSON.stringify({ | ||
...body, | ||
...(await this.signatureFor()) | ||
})); | ||
} | ||
@@ -233,3 +237,3 @@ } | ||
amount: (deposit && deposit.toString()) || undefined, | ||
deposit: (deposit && deposit.toString()) || undefined, | ||
deposit: (deposit && deposit.toString()) || '0', | ||
permission: undefined, | ||
@@ -236,0 +240,0 @@ }; |
'use strict'; | ||
import BN from 'bn.js'; | ||
import { Action, transfer, createAccount, signTransaction, deployContract, | ||
addKey, functionCall, fullAccessKey, functionCallAccessKey, deleteKey, stake, AccessKey, deleteAccount } from './transaction'; | ||
import { | ||
transfer, | ||
createAccount, | ||
signTransaction, | ||
deployContract, | ||
addKey, | ||
functionCall, | ||
fullAccessKey, | ||
functionCallAccessKey, | ||
deleteKey, | ||
stake, | ||
deleteAccount, | ||
AccessKey, | ||
Action, | ||
SignedTransaction | ||
} from './transaction'; | ||
import { FinalExecutionOutcome, TypedError, ErrorContext } from './providers'; | ||
@@ -107,2 +121,20 @@ import { Connection } from './connection'; | ||
protected async signTransaction(receiverId: string, actions: Action[]): Promise<[Uint8Array, SignedTransaction]> { | ||
await this.ready; | ||
const accessKeyInfo = await this.findAccessKey(receiverId, actions); | ||
if (!accessKeyInfo) { | ||
throw new TypedError(`Can not sign transactions for account ${this.accountId} on network ${this.connection.networkId}, no matching key pair found in ${this.connection.signer}.`, 'KeyNotFound'); | ||
} | ||
const { accessKey } = accessKeyInfo; | ||
const status = await this.connection.provider.status(); | ||
const nonce = ++accessKey.nonce; | ||
// TODO: get latest_block_hash from block query using `final` finality | ||
return await signTransaction( | ||
receiverId, nonce, actions, base_decode(status.sync_info.latest_block_hash), this.connection.signer, this.accountId, this.connection.networkId | ||
); | ||
} | ||
/** | ||
@@ -119,15 +151,5 @@ * @param receiverId NEAR account receiving the transaction | ||
const result = await exponentialBackoff(TX_STATUS_RETRY_WAIT, TX_NONCE_RETRY_NUMBER, TX_STATUS_RETRY_WAIT_BACKOFF, async () => { | ||
const accessKeyInfo = await this.findAccessKey(receiverId, actions); | ||
if (!accessKeyInfo) { | ||
throw new TypedError(`Can not sign transactions for account ${this.accountId} on network ${this.connection.networkId}, no matching key pair found in ${this.connection.signer}.`, 'KeyNotFound'); | ||
} | ||
const { publicKey, accessKey } = accessKeyInfo; | ||
[txHash, signedTx] = await this.signTransaction(receiverId, actions); | ||
const publicKey = signedTx.transaction.publicKey; | ||
const status = await this.connection.provider.status(); | ||
const nonce = ++accessKey.nonce; | ||
[txHash, signedTx] = await signTransaction( | ||
receiverId, nonce, actions, base_decode(status.sync_info.latest_block_hash), this.connection.signer, this.accountId, this.connection.networkId | ||
); | ||
try { | ||
@@ -134,0 +156,0 @@ const result = await exponentialBackoff(TX_STATUS_RETRY_WAIT, TX_STATUS_RETRY_NUMBER, TX_STATUS_RETRY_WAIT_BACKOFF, async () => { |
@@ -7,5 +7,5 @@ import BN from 'bn.js'; | ||
// Makes `function.name` return given name | ||
function nameFunction(name, body) { | ||
function nameFunction(name: string, body: (args?: any[]) => {}) { | ||
return { | ||
[name](...args) { | ||
[name](...args: any[]) { | ||
return body(...args); | ||
@@ -16,2 +16,8 @@ } | ||
const isUint8Array = (x: any) => | ||
x && x.byteLength !== undefined && x.byteLength === x.length; | ||
const isObject = (x: any) => | ||
Object.prototype.toString.call(x) === '[object Object]'; | ||
/** | ||
@@ -24,3 +30,3 @@ * Defines a smart contract on NEAR including the mutable and non-mutable methods | ||
constructor(account: Account, contractId: string, options: { viewMethods: string[], changeMethods: string[] }) { | ||
constructor(account: Account, contractId: string, options: { viewMethods: string[]; changeMethods: string[] }) { | ||
this.account = account; | ||
@@ -34,3 +40,3 @@ this.contractId = contractId; | ||
value: nameFunction(methodName, async (args: object = {}, ...ignored) => { | ||
if (ignored.length || Object.prototype.toString.call(args) !== '[object Object]') { | ||
if (ignored.length || !(isObject(args) || isUint8Array(args))) { | ||
throw new PositionalArgsError(); | ||
@@ -47,3 +53,3 @@ } | ||
value: nameFunction(methodName, async (args: object = {}, gas?: BN, amount?: BN, ...ignored) => { | ||
if (ignored.length || Object.prototype.toString.call(args) !== '[object Object]') { | ||
if (ignored.length || !(isObject(args) || isUint8Array(args))) { | ||
throw new PositionalArgsError(); | ||
@@ -50,0 +56,0 @@ } |
@@ -13,10 +13,11 @@ | ||
type NearConfig = { | ||
keyStore?: KeyStore, | ||
signer?: Signer, | ||
deps?: { keyStore: KeyStore } | ||
helperUrl?: string | ||
initialBalance?: string | ||
masterAccount?: string | ||
networkId: string | ||
nodeUrl: string | ||
keyStore?: KeyStore; | ||
signer?: Signer; | ||
deps?: { keyStore: KeyStore }; | ||
helperUrl?: string; | ||
initialBalance?: string; | ||
masterAccount?: string; | ||
networkId: string; | ||
nodeUrl: string; | ||
walletUrl?: string; | ||
} | ||
@@ -76,3 +77,3 @@ | ||
*/ | ||
async loadContract(contractId: string, options: { viewMethods: string[], changeMethods: string[], sender: string }): Promise<Contract> { | ||
async loadContract(contractId: string, options: { viewMethods: string[]; changeMethods: string[]; sender: string }): Promise<Contract> { | ||
const account = new Account(this.connection, options.sender); | ||
@@ -97,3 +98,3 @@ return new Contract(account, contractId, options); | ||
type ConnectConfig = NearConfig & { | ||
keyPath?: string | ||
keyPath?: string; | ||
} | ||
@@ -100,0 +101,0 @@ |
import depd from 'depd'; | ||
import { | ||
Provider, FinalExecutionOutcome, NodeStatusResult, BlockId, Finality, | ||
BlockResult, ChunkId, ChunkResult, adaptTransactionResult, EpochValidatorInfo, | ||
BlockResult, ChunkId, ChunkResult, EpochValidatorInfo, | ||
GenesisConfig, LightClientProof, LightClientProofRequest | ||
@@ -55,3 +55,3 @@ } from './provider'; | ||
const bytes = signedTransaction.encode(); | ||
return this.sendJsonRpc('broadcast_tx_commit', [Buffer.from(bytes).toString('base64')]).then(adaptTransactionResult); | ||
return this.sendJsonRpc('broadcast_tx_commit', [Buffer.from(bytes).toString('base64')]); | ||
} | ||
@@ -67,3 +67,3 @@ | ||
async txStatus(txHash: Uint8Array, accountId: string): Promise<FinalExecutionOutcome> { | ||
return this.sendJsonRpc('tx', [base_encode(txHash), accountId]).then(adaptTransactionResult); | ||
return this.sendJsonRpc('tx', [base_encode(txHash), accountId]); | ||
} | ||
@@ -70,0 +70,0 @@ |
@@ -263,14 +263,1 @@ import { Network } from '../utils/network'; | ||
} | ||
export function adaptTransactionResult(txResult: any): FinalExecutionOutcome { | ||
if ('receipts' in txResult) { | ||
txResult = { | ||
status: txResult.status, | ||
// not available | ||
transaction: null, | ||
transaction_outcome: txResult.transaction, | ||
receipts_outcome: txResult.receipts | ||
}; | ||
} | ||
return txResult; | ||
} |
@@ -52,2 +52,6 @@ const { Contract } = require('../lib/contract'); | ||
}); | ||
test('allows args encoded as Uint8Array (for borsh)', async () => { | ||
expect(await contract[method](new Uint8Array())); | ||
}); | ||
}); | ||
@@ -54,0 +58,0 @@ }); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2309291
29296
51
18
174
Updatednode-fetch@^2.6.1