diff --git a/modules/bitgo/src/v2/coinFactory.ts b/modules/bitgo/src/v2/coinFactory.ts index 431c8bf2f7..36f2cf0991 100644 --- a/modules/bitgo/src/v2/coinFactory.ts +++ b/modules/bitgo/src/v2/coinFactory.ts @@ -5,7 +5,7 @@ import { AdaToken } from '@bitgo/sdk-coin-ada'; import { AlgoToken } from '@bitgo/sdk-coin-algo'; import { Bcha, Tbcha } from '@bitgo/sdk-coin-bcha'; import { HbarToken } from '@bitgo/sdk-coin-hbar'; -import { Near, TNear } from '@bitgo/sdk-coin-near'; +import { Near, TNear, Nep141Token } from '@bitgo/sdk-coin-near'; import { SolToken } from '@bitgo/sdk-coin-sol'; import { TrxToken } from '@bitgo/sdk-coin-trx'; import { CoinFactory } from '@bitgo/sdk-core'; @@ -451,6 +451,10 @@ export function registerCoinConstructors(coinFactory: CoinFactory, coinMap: Coin Sip10Token.createTokenConstructors([...tokens.bitcoin.stx.tokens, ...tokens.testnet.stx.tokens]).forEach( ({ name, coinConstructor }) => coinFactory.register(name, coinConstructor) ); + + Nep141Token.createTokenConstructors([...tokens.bitcoin.near.tokens, ...tokens.testnet.near.tokens]).forEach( + ({ name, coinConstructor }) => coinFactory.register(name, coinConstructor) + ); } export const GlobalCoinFactory: CoinFactory = new CoinFactory(); diff --git a/modules/bitgo/test/browser/browser.spec.ts b/modules/bitgo/test/browser/browser.spec.ts index e7835a4cae..3cbc6cba5e 100644 --- a/modules/bitgo/test/browser/browser.spec.ts +++ b/modules/bitgo/test/browser/browser.spec.ts @@ -43,6 +43,7 @@ describe('Coins', () => { Polyx: 1, Tpolyx: 1, CoredaoToken: 1, + Nep141Token: 1, }; Object.keys(BitGoJS.Coin) .filter((coinName) => !excludedKeys[coinName]) diff --git a/modules/sdk-coin-near/package.json b/modules/sdk-coin-near/package.json index 1226bd862e..7be2a316a7 100644 --- a/modules/sdk-coin-near/package.json +++ b/modules/sdk-coin-near/package.json @@ -42,13 +42,14 @@ "dependencies": { "@bitgo/sdk-core": "^35.0.0", "@bitgo/statics": "^54.0.0", + "@near-js/crypto": "^2.0.1", + "@near-js/transactions": "^2.0.1", "@stablelib/hex": "^1.0.0", "bignumber.js": "^9.0.0", - "bn.js": "^5.2.1", "bs58": "^4.0.1", "js-sha256": "^0.9.0", "lodash": "^4.17.14", - "near-api-js": "^0.44.2", + "near-api-js": "^5.1.1", "superagent": "^9.0.1", "tweetnacl": "^1.0.3" }, diff --git a/modules/sdk-coin-near/src/lib/abstractDelegateBuilder.ts b/modules/sdk-coin-near/src/lib/abstractDelegateBuilder.ts new file mode 100644 index 0000000000..ffd122a751 --- /dev/null +++ b/modules/sdk-coin-near/src/lib/abstractDelegateBuilder.ts @@ -0,0 +1,244 @@ +import assert from 'assert'; +import BigNumber from 'bignumber.js'; + +import * as hex from '@stablelib/hex'; +import * as nearAPI from 'near-api-js'; +import { DelegateAction } from '@near-js/transactions'; + +import { + BaseAddress, + BaseKey, + BaseTransactionBuilder, + BuildTransactionError, + PublicKey as BasePublicKey, + Signature, +} from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; + +import { AddressValidationError } from './errors'; +import { BLOCK_HEIGHT_TTL } from './constants'; +import { DelegateTransaction } from './delegateTransaction'; +import { InitializableBuilder } from './initializableBuilder'; +import { KeyPair } from './keyPair'; +import utils from './utils'; + +export abstract class AbstractDelegateBuilder extends BaseTransactionBuilder implements InitializableBuilder { + private _delegateTransaction: DelegateTransaction; + + private _sender: string; + private _publicKey: string; + protected _receiverId: string; + private _nonce: bigint; + private _recentBlockHeight: bigint; + private _signer: KeyPair; + private _signatures: Signature[] = []; + protected _actions: nearAPI.transactions.Action[]; + + constructor(_coinConfig: Readonly) { + super(_coinConfig); + this._delegateTransaction = new DelegateTransaction(_coinConfig); + } + + /** + * Initialize the transaction builder fields using the decoded transaction data + * + * @param {Transaction} tx the transaction data + */ + initBuilder(tx: DelegateTransaction): void { + this._delegateTransaction = tx; + const nearDelegateAction = tx.nearTransaction; + this._sender = nearDelegateAction.senderId; + this._nonce = nearDelegateAction.nonce; + this._receiverId = nearDelegateAction.receiverId; + if (nearDelegateAction.publicKey.ed25519Key?.data) { + this._publicKey = hex.encode(nearDelegateAction.publicKey.ed25519Key.data); + } + this._recentBlockHeight = nearDelegateAction.maxBlockHeight; + this._actions = nearDelegateAction.actions; + } + + /** @inheritdoc */ + protected fromImplementation(rawTransaction: string): DelegateTransaction { + this.validateRawTransaction(rawTransaction); + this.buildImplementation(); + return this.transaction; + } + + /** @inheritdoc */ + protected async buildImplementation(): Promise { + this.transaction.nearTransaction = this.buildNearTransaction(); + if (this._signer) { + this.transaction.sign(this._signer); + } + if (this._signatures?.length > 0) { + this.transaction.constructSignedPayload(this._signatures[0].signature); + } + this.transaction.loadInputsAndOutputs(); + return this.transaction; + } + + /** @inheritdoc */ + protected signImplementation(key: BaseKey): DelegateTransaction { + this._signer = new KeyPair({ prv: key.key }); + return this._delegateTransaction; + } + + /** @inheritdoc */ + protected get transaction(): DelegateTransaction { + return this._delegateTransaction; + } + + /** @inheritdoc */ + protected set transaction(transaction: DelegateTransaction) { + this._delegateTransaction = transaction; + } + + /** @inheritdoc */ + validateAddress(address: BaseAddress, addressFormat?: string): void { + if (!utils.isValidAddress(address.address)) { + throw new AddressValidationError(address.address); + } + } + + /** @inheritdoc */ + validateKey(key: BaseKey): void { + try { + new KeyPair({ prv: key.key }); + } catch { + throw new BuildTransactionError(`Key validation failed`); + } + } + + /** @inheritdoc */ + validateRawTransaction(rawTransaction: any): void { + try { + nearAPI.utils.serialize.deserialize(nearAPI.transactions.SCHEMA.SignedDelegate, rawTransaction); + } catch { + try { + nearAPI.utils.serialize.deserialize(nearAPI.transactions.SCHEMA.DelegateAction, rawTransaction); + } catch { + throw new BuildTransactionError('invalid raw transaction'); + } + } + } + + /** @inheritdoc */ + validateTransaction(transaction: DelegateTransaction): void { + if (!transaction.nearTransaction) { + return; + } + this.validateAddress({ address: transaction.nearTransaction.senderId }); + this.validateAddress({ address: transaction.nearTransaction.receiverId }); + } + + /** @inheritdoc */ + validateValue(value: BigNumber): void { + if (value.isLessThan(0)) { + throw new BuildTransactionError('Value cannot be less than zero'); + } + } + + /** + * Sets the public key and the address of the sender of this transaction. + * + * @param {string} address the account that is sending this transaction + * @param {string} pubKey the public key that is sending this transaction + * @returns {AbstractDelegateBuilder} The delegate transaction builder + */ + public sender(address: string, pubKey: string): this { + if (!address || !utils.isValidAddress(address.toString())) { + throw new BuildTransactionError('Invalid or missing address, got: ' + address); + } + if (!pubKey || !utils.isValidPublicKey(pubKey)) { + throw new BuildTransactionError('Invalid or missing pubKey, got: ' + pubKey); + } + this._sender = address; + this._publicKey = pubKey; + return this; + } + + /** + * Sets the account id of the receiver of this transaction. + * + * @param {string} accountId the account id of the account that is receiving this transaction + * @returns {AbstractDelegateBuilder} The delegate transaction builder + */ + public receiverId(accountId: string): this { + utils.isValidAddress(accountId); + this._receiverId = accountId; + return this; + } + + /** + * Set the nonce + * + * @param {bigint} nonce - number that can be only used once + * @returns {AbstractDelegateBuilder} This delegate transaction builder + */ + public nonce(nonce: bigint): this { + if (nonce < 0) { + throw new BuildTransactionError(`Invalid nonce: ${nonce}`); + } + this._nonce = nonce; + return this; + } + + /** + * Sets the recent block height for this transaction + * + * @param {string} blockHeight the blockHeight of this transaction + * @returns {AbstractDelegateBuilder} The delegate transaction builder + */ + public recentBlockHeight(blockHeight: bigint): this { + this._recentBlockHeight = blockHeight; + return this; + } + + /** + * Sets the list of actions of this transaction. + * + * @param {nearAPI.transactions.Action[]} value the list of actions + * @returns {AbstractDelegateBuilder} The delegate transaction builder + */ + protected actions(value: nearAPI.transactions.Action[]): this { + this._actions = value; + return this; + } + + /** + * Sets the action for this transaction/ + * + * @param {nearAPI.transactions.Action} value the delegate action + * @returns {AbstractDelegateBuilder} The delegate transaction builder + */ + protected action(value: nearAPI.transactions.Action): this { + this._actions ? this._actions.push(value) : (this._actions = [value]); + return this; + } + + /** + * Builds the NEAR delegate action. + * + * @return {DelegateAction} near sdk delegate action + */ + protected buildNearTransaction(): DelegateAction { + assert(this._sender, new BuildTransactionError('sender is required before building')); + assert(this._recentBlockHeight, new BuildTransactionError('recent block height is required before building')); + + const tx = new DelegateAction({ + senderId: this._sender, + receiverId: this._receiverId, + actions: this._actions, + nonce: this._nonce, + maxBlockHeight: BigInt(BLOCK_HEIGHT_TTL + this._recentBlockHeight), + publicKey: nearAPI.utils.PublicKey.fromString(nearAPI.utils.serialize.base_encode(hex.decode(this._publicKey))), + }); + + return tx; + } + + /** @inheritDoc */ + addSignature(publicKey: BasePublicKey, signature: Buffer): void { + this._signatures.push({ publicKey, signature }); + } +} diff --git a/modules/sdk-coin-near/src/lib/constants.ts b/modules/sdk-coin-near/src/lib/constants.ts index 33d9886b10..3965a61718 100644 --- a/modules/sdk-coin-near/src/lib/constants.ts +++ b/modules/sdk-coin-near/src/lib/constants.ts @@ -9,4 +9,11 @@ export const StakingContractMethodNames = { Withdraw: 'withdraw', } as const; +export const AdditionalAllowedMethods = ['ft_transfer', 'storage_deposit']; + +export const FT_TRANSFER = 'ft_transfer'; +export const STORAGE_DEPOSIT = 'storage_deposit'; + export const HEX_REGEX = /^[0-9a-fA-F]+$/; + +export const BLOCK_HEIGHT_TTL = 120n; diff --git a/modules/sdk-coin-near/src/lib/contractCallWrapper.ts b/modules/sdk-coin-near/src/lib/contractCallWrapper.ts index 8a4f068fa1..8fff35d0b7 100644 --- a/modules/sdk-coin-near/src/lib/contractCallWrapper.ts +++ b/modules/sdk-coin-near/src/lib/contractCallWrapper.ts @@ -7,7 +7,7 @@ import { FunctionCall } from './iface'; */ export class ContractCallWrapper { private _methodName: string; - private _args: Record; + private _args: Record = {}; private _gas: string; private _deposit: string; @@ -21,7 +21,7 @@ export class ContractCallWrapper { return this._methodName; } - /** Set gas, expresed on yocto */ + /** Set gas, expressed on yocto */ public set gas(gas: string) { if (!this.isValidAmount(new BigNumber(gas))) { throw new InvalidParameterValueError('Invalid gas value'); @@ -29,12 +29,12 @@ export class ContractCallWrapper { this._gas = gas; } - /** Get gas, expresed on yocto*/ + /** Get gas, expressed on yocto*/ public get gas(): string { return this._gas; } - /** Set deposit, expresed on yocto */ + /** Set deposit, expressed on yocto */ public set deposit(deposit: string) { if (!this.isValidAmount(new BigNumber(deposit))) { throw new InvalidParameterValueError('Invalid deposit value'); @@ -42,14 +42,14 @@ export class ContractCallWrapper { this._deposit = deposit; } - /** Get deposit, expresed on yocto */ + /** Get deposit, expressed on yocto */ public get deposit(): string { return this._deposit; } /** Get args, which are the parameters of a method */ public set args(args: Record) { - this._args = args; + this._args = { ...this._args, ...args }; } /** Set args, which are the parameters of a method */ diff --git a/modules/sdk-coin-near/src/lib/delegateTransaction.ts b/modules/sdk-coin-near/src/lib/delegateTransaction.ts new file mode 100644 index 0000000000..2effb11766 --- /dev/null +++ b/modules/sdk-coin-near/src/lib/delegateTransaction.ts @@ -0,0 +1,501 @@ +import { Buffer } from 'buffer'; +import base58 from 'bs58'; +import { sha256 } from 'js-sha256'; +import * as nearAPI from 'near-api-js'; + +import { + Action as NearAction, + DelegateAction, + encodeDelegateAction, + encodeSignedDelegate, + SignedDelegate, +} from '@near-js/transactions'; +import { KeyType } from '@near-js/crypto'; + +import { + BaseKey, + BaseTransaction, + Entry, + InvalidTransactionError, + ITransactionRecipient, + TransactionRecipient, + TransactionType, +} from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; + +import { Action, Signature, TransactionExplanation, TxData } from './iface'; +import { AdditionalAllowedMethods } from './constants'; +import utils from './utils'; +import { KeyPair } from './keyPair'; + +export class DelegateTransaction extends BaseTransaction { + private _nearDelegateAction: DelegateAction; + private _nearSignedDelegateAction: SignedDelegate; + + constructor(coinConfig: Readonly) { + super(coinConfig); + } + + get nearTransaction(): DelegateAction { + return this._nearDelegateAction; + } + + set nearTransaction(tx: DelegateAction) { + this._nearDelegateAction = tx; + this._id = utils.base58Encode(this.getTransactionHash()); + } + + /** + * Initiates the delegate transaction from signed delegate object + * @param {CoinConfig} coinConfig the coin config + * @param {SignedDelegate} signedDelegate the signed delegate object + * @returns {DelegateTransaction} tx the delegate transaction + */ + static fromSigned(coinConfig: Readonly, signedDelegate: SignedDelegate): DelegateTransaction { + const tx = new DelegateTransaction(coinConfig); + tx.initFromSigned(signedDelegate); + return tx; + } + + /** + * Initiates the delegate transaction from unsigned delegate action + * @param {CoinConfig} coinConfig the coin config + * @param {DelegateAction} delegateAction the unsigned delegate action + * @returns {DelegateTransaction} tx the delegate transaction + */ + static fromUnsigned(coinConfig: Readonly, delegateAction: DelegateAction): DelegateTransaction { + const tx = new DelegateTransaction(coinConfig); + tx.initFromUnsigned(delegateAction); + return tx; + } + + /** + * Assigns the signed delegate to class variables + * + * @param {SignedDelegate} signedDelegate the signed delegate object + * @returns {void} + */ + private initFromSigned(signedDelegate: SignedDelegate): void { + this._nearSignedDelegateAction = signedDelegate; + this._nearDelegateAction = signedDelegate.delegateAction; + this._id = utils.base58Encode(this.getTransactionHash()); + this.loadInputsAndOutputs(); + } + + /** + * Assigns the delegate action to class variables + * + * @param {DelegateAction} delegateAction the unsigned delegate action + * @returns {void} + */ + private initFromUnsigned(delegateAction: DelegateAction): void { + this._nearDelegateAction = delegateAction; + this._id = utils.base58Encode(this.getTransactionHash()); + this.loadInputsAndOutputs(); + } + + /** @inheritdoc */ + canSign(key: BaseKey): boolean { + try { + new KeyPair({ prv: key.key }); + return true; + } catch { + return false; + } + } + + /** @inheritdoc */ + toBroadcastFormat(): string { + if (!this._nearDelegateAction) { + throw new InvalidTransactionError('Empty transaction data'); + } + return this._nearSignedDelegateAction + ? Buffer.from(encodeSignedDelegate(this._nearSignedDelegateAction)).toString('base64') + : Buffer.from(encodeDelegateAction(this._nearDelegateAction)).toString('base64'); + } + + /** @inheritdoc */ + toJson(): TxData { + if (!this._nearDelegateAction) { + throw new InvalidTransactionError('Empty delegation data'); + } + + const parsedActions: Action[] = []; + const actions = this._nearDelegateAction.actions; + actions.map((action) => { + let parsedAction: Action = {}; + if (action.enum === 'transfer' && action.transfer) { + parsedAction = { transfer: action.transfer }; + } else if (action.enum === 'functionCall' && action.functionCall) { + const functionCall = action.functionCall; + parsedAction = { + functionCall: { + methodName: functionCall.methodName, + args: JSON.parse(Buffer.from(functionCall.args).toString()), + gas: functionCall.gas.toString(), + deposit: functionCall.deposit.toString(), + }, + }; + } + parsedActions.push(parsedAction); + }); + let signature: Signature | undefined; + if (this._nearSignedDelegateAction?.signature?.ed25519Signature) { + signature = { + keyType: KeyType.ED25519, + data: new Uint8Array(this._nearSignedDelegateAction.signature.ed25519Signature.data), + }; + } + let publicKey: string | undefined; + if (this._nearDelegateAction.publicKey?.ed25519Key) { + const rawBytes = new Uint8Array(this._nearDelegateAction.publicKey.ed25519Key.data); + const encoded = nearAPI.utils.serialize.base_encode(rawBytes); + publicKey = `ed25519Key.${encoded}`; + } + + return { + id: this._id, + signerId: this._nearDelegateAction.senderId, + publicKey: publicKey, + nonce: this._nearDelegateAction.nonce, + receiverId: this._nearDelegateAction.receiverId, + actions: parsedActions, + signature: signature ? signature : undefined, + }; + } + + /** + * Set the transaction type. + * + * @param {TransactionType} transactionType The transaction type to be set. + * @returns {void} + */ + setTransactionType(transactionType: TransactionType): void { + this._type = transactionType; + } + + /** + * Sign this transaction + * + * @param {KeyPair} signer key + * @returns {void} + */ + sign(signer: KeyPair): void { + if (!this._nearDelegateAction) { + throw new InvalidTransactionError('empty transaction to sign'); + } + const serializedTxHash = this.getTransactionHash(); + const signature = signer.signMessageinUint8Array(serializedTxHash); + this._nearSignedDelegateAction = new SignedDelegate({ + delegateAction: this._nearDelegateAction, + signature: new nearAPI.transactions.Signature({ + keyType: this._nearDelegateAction.publicKey.keyType, + data: signature, + }), + }); + this.loadInputsAndOutputs(); + } + + /** + * Check if method name allowed for delegate transaction call + * + * @param {String} methodName method name of delegate action + * @returns {Boolean} true if method name is allowed + */ + private isAllowedMethod(methodName: string): boolean { + return AdditionalAllowedMethods.includes(methodName); + } + + /** + * Check if action is valid for delegate transaction + * + * @param {Array} actions the list of near actions + * @returns {Boolean} true if actions is valid for delegate transaction + */ + private isValidActions(actions: Array): boolean { + return actions.every((action) => { + if (!action.functionCall) return false; + + const methodName = action.functionCall.methodName; + return this.isAllowedMethod(methodName); + }); + } + + /** + * Checks if fungible token transfer action present in list of actions + * + * @param {Array} actions the list of near actions + * @returns {Boolean} true if at least one action is ft transfer action + */ + private isTokenTransferActionPresent(actions: Array): boolean { + return actions.some((action) => action.functionCall?.methodName === 'ft_transfer'); + } + + /** + * Checks if all actions are storage deposit actions + * + * @param {Array} actions the list of near actions + * @returns {Boolean} true if all actions are storage deposit + */ + private isAllActionsAreStorageDeposit(actions: Array): boolean { + return actions.every((action) => action.functionCall?.methodName === 'storage_deposit'); + } + + /** + * Load input and output field for this transaction + * In delegate we only support functionCall action (ft_transfer and/or storage_deposit) and + * batching of multiple ft_transfers or ft_transfer with storage_deposit + * + * @returns {void} + */ + loadInputsAndOutputs(): void { + const actions = this._nearDelegateAction.actions; + if (!this.isValidActions(actions)) { + throw new InvalidTransactionError('unsupported action(s) in raw transaction'); + } + + if (this.isTokenTransferActionPresent(actions)) { + this.setTransactionType(TransactionType.SendToken); + } else if (this.isAllActionsAreStorageDeposit(actions)) { + this.setTransactionType(TransactionType.StorageDeposit); + } + + const outputs: Entry[] = []; + const inputs: Entry[] = []; + + actions.map((action) => { + switch (this.type) { + case TransactionType.SendToken: { + if (action.functionCall) { + if (action.functionCall.methodName === 'ft_transfer') { + const parsedArgs = JSON.parse(Buffer.from(action.functionCall.args).toString()); + inputs.push({ + address: parsedArgs.receiver_id, + value: parsedArgs.amount, + coin: this._coinConfig.name, + }); + outputs.push({ + address: this._nearDelegateAction.senderId, + value: parsedArgs.amount, + coin: this._coinConfig.name, + }); + } + if (action.functionCall.methodName === 'storage_deposit') { + const parsedArgs = JSON.parse(Buffer.from(action.functionCall.args).toString()); + const receiverId = parsedArgs.account_id ? parsedArgs.account_id : this._nearDelegateAction.senderId; + inputs.push({ + address: receiverId, + value: action.functionCall.deposit.toString(), + coin: this._coinConfig.family, + }); + outputs.push({ + address: this._nearDelegateAction.senderId, + value: action.functionCall.deposit.toString(), + coin: this._coinConfig.family, + }); + } + } + break; + } + case TransactionType.StorageDeposit: { + if (action.functionCall) { + const parsedArgs = JSON.parse(Buffer.from(action.functionCall.args).toString()); + const receiverId = parsedArgs.account_id ? parsedArgs.account_id : this._nearDelegateAction.senderId; + inputs.push({ + address: receiverId, + value: action.functionCall.deposit.toString(), + coin: this._coinConfig.family, + }); + outputs.push({ + address: this._nearDelegateAction.senderId, + value: action.functionCall.deposit.toString(), + coin: this._coinConfig.family, + }); + } + break; + } + default: + break; + } + }); + this._outputs = outputs; + this._inputs = inputs; + } + + /** + * Calculates the total fungible token amount & total native near amount + * + * @param {Action[]} actions the list of delegate transaction actions + * @returns {String} either native near amount or fungible token amount + */ + calculateTotalOutputAmount(actions: Action[]): string { + let hasFtTransfer = false; + let hasStorageDeposit = false; + + let totalTokenAmount = BigInt(0); + let totalNearDeposit = BigInt(0); + + for (const action of actions) { + if (action.functionCall) { + const functionCall = action.functionCall; + const methodName = functionCall.methodName; + const args = functionCall.args; + const deposit = BigInt(functionCall.deposit); + if (methodName === 'ft_transfer') { + hasFtTransfer = true; + const amountStr = args['amount'] as string; + if (args.amount) { + totalTokenAmount += BigInt(amountStr); + } + } + if (methodName === 'storage_deposit') { + hasStorageDeposit = true; + totalNearDeposit += deposit; + } + } + } + if (hasFtTransfer && hasStorageDeposit) { + return totalTokenAmount.toString(); + } else if (!hasFtTransfer && hasStorageDeposit) { + return totalNearDeposit.toString(); + } + return ''; + } + + /** + * Returns a complete explanation for a token transfer transaction + * @param {TxData} json The transaction data in json format + * @param {TransactionExplanation} explanationResult The transaction explanation to be completed + * @returns {TransactionExplanation} + */ + explainTokenTransferTransaction(json: TxData, explanationResult: TransactionExplanation): TransactionExplanation { + const actions = json.actions; + const outputAmount = this.calculateTotalOutputAmount(actions); + const outputs: ITransactionRecipient[] = []; + actions.map((action) => { + if (action.functionCall) { + const functionCall = action.functionCall; + if (functionCall.methodName === 'ft_transfer') { + const amountStr = functionCall.args['amount'] as string; + outputs.push({ + address: json.receiverId, + amount: amountStr, + }); + } + } + }); + return { + ...explanationResult, + outputAmount: outputAmount, + outputs: outputs, + }; + } + + /** + * Returns a complete explanation for a storage deposit transaction + * @param {TxData} json The transaction data in json format + * @param {TransactionExplanation} explanationResult The transaction explanation to be completed + * @returns {TransactionExplanation} + */ + explainStorageDepositTransaction(json: TxData, explanationResult: TransactionExplanation): TransactionExplanation { + const actions = json.actions; + const outputAmount = this.calculateTotalOutputAmount(actions); + const outputs: ITransactionRecipient[] = []; + actions.map((action) => { + if (action.functionCall) { + const functionCall = action.functionCall; + if (functionCall.methodName === 'storage_deposit') { + outputs.push({ + address: json.receiverId, + amount: functionCall.deposit, + }); + } + } + }); + return { + ...explanationResult, + outputAmount: outputAmount, + outputs: outputs, + }; + } + + /** @inheritdoc */ + explainTransaction(): TransactionExplanation { + const result = this.toJson(); + const displayOrder = ['outputAmount', 'changeAmount', 'outputs', 'changeOutputs', 'fee', 'type']; + const outputs: TransactionRecipient[] = []; + const explanationResult: TransactionExplanation = { + // txhash used to identify the transactions + id: result.id || '', + displayOrder, + outputAmount: '0', + changeAmount: '0', + changeOutputs: [], + outputs, + fee: { fee: '' }, + type: this.type, + }; + switch (this.type) { + case TransactionType.SendToken: + return this.explainTokenTransferTransaction(result, explanationResult); + case TransactionType.StorageDeposit: + return this.explainStorageDepositTransaction(result, explanationResult); + default: + throw new InvalidTransactionError('Transaction type not supported'); + } + } + + /** + * Get the serialized transaction hash + * + * @returns {Uint8Array} serialized hash in Uint8Array form + */ + private getTransactionHash(): Uint8Array { + const serializedTx = nearAPI.utils.serialize.serialize( + nearAPI.transactions.SCHEMA.DelegateAction, + this._nearDelegateAction + ); + return new Uint8Array(sha256.array(serializedTx)); + } + + /** + * Get the signable payload for the delegate action + * + * @returns {Buffer} + */ + get signablePayload(): Buffer { + if (!this._nearDelegateAction) { + throw new InvalidTransactionError('empty transaction'); + } + return Buffer.from(this.getTransactionHash()); + } + + /** + * Constructs a signed payload using construct.signTx + * This method will be called during the build step if a TSS signature + * is added and will set the signTransaction which is the txHex that will be broadcasted + * As well as add the signature used to sign to the signature array in hex format + * + * @param {Buffer} signature The signature to be added to a near transaction + */ + constructSignedPayload(signature: Buffer): void { + this._nearSignedDelegateAction = new SignedDelegate({ + delegateAction: this._nearDelegateAction, + signature: new nearAPI.transactions.Signature({ + keyType: this._nearDelegateAction.publicKey.keyType, + data: signature, + }), + }); + this.loadInputsAndOutputs(); + } + /** @inheritdoc **/ + get signature(): string[] { + const signatures: string[] = []; + + if (this._nearSignedDelegateAction && this._nearSignedDelegateAction.signature.ed25519Signature) { + signatures.push(base58.encode(this._nearSignedDelegateAction.signature.ed25519Signature.data)); + } + + return signatures; + } +} diff --git a/modules/sdk-coin-near/src/lib/fungibleTokenTransferBuilder.ts b/modules/sdk-coin-near/src/lib/fungibleTokenTransferBuilder.ts new file mode 100644 index 0000000000..d808c28c4b --- /dev/null +++ b/modules/sdk-coin-near/src/lib/fungibleTokenTransferBuilder.ts @@ -0,0 +1,129 @@ +import assert from 'assert'; +import BigNumber from 'bignumber.js'; +import * as NearAPI from 'near-api-js'; + +import { BuildTransactionError, TransactionType } from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; + +import { FT_TRANSFER } from './constants'; +import { ContractCallWrapper } from './contractCallWrapper'; +import { AbstractDelegateBuilder } from './abstractDelegateBuilder'; +import { DelegateTransaction } from './delegateTransaction'; +import utils from './utils'; +import { StorageDepositInput } from './iface'; + +export class FungibleTokenTransferBuilder extends AbstractDelegateBuilder { + private contractCallWrapper: ContractCallWrapper; + + constructor(_coinConfig: Readonly) { + super(_coinConfig); + this.contractCallWrapper = new ContractCallWrapper(); + this.contractCallWrapper.methodName = FT_TRANSFER; + } + + /** + * Initialize the transaction builder fields using the decoded transaction data + * + * @param {DelegateTransaction} tx the transaction data + */ + initBuilder(tx: DelegateTransaction): void { + super.initBuilder(tx); + for (const action of tx.nearTransaction.actions) { + if (action.functionCall && action.functionCall.methodName === FT_TRANSFER) { + this.contractCallWrapper.deposit = action.functionCall.deposit.toString(); + this.contractCallWrapper.gas = action.functionCall.gas.toString(); + } + } + } + + /** + * Sets the gas of this transaction. + * + * @param {String} gas the gas of this transaction + * @returns {TransactionBuilder} This transaction builder + */ + public gas(gas: string): this { + this.validateValue(new BigNumber(gas)); + this.contractCallWrapper.gas = gas; + return this; + } + + /** + * Sets the deposit of at-least 1 yoctoNear + * + * @param {string} deposit the deposit in the minimum unit (1 Near = 1e24 yoctoNear) of this transaction + * @returns {TransactionBuilder} This transaction builder + */ + public deposit(deposit: string): this { + this.validateValue(new BigNumber(deposit)); + this.contractCallWrapper.deposit = deposit; + return this; + } + + /** + * @inheritdoc + * + * We need to override this because for contract call the receiver id is the contract address + * And we need to pass the actual receiver id in the args + * + * @param accountId the contract address + */ + public receiverId(accountId: string): this { + utils.isValidAddress(accountId); + this._receiverId = accountId; + return this; + } + + /** + * Sets the actual receiver account id inside args + * + * @param accountId the receiver account id + */ + public ftReceiverId(accountId: string): this { + utils.isValidAddress(accountId); + this.contractCallWrapper.args = { receiver_id: accountId }; + return this; + } + + /** + * Sets the ft amount to be transferred + * + * @param amount the amount of fungible token to be transferred + */ + public amount(amount: string): this { + this.validateValue(new BigNumber(amount)); + this.contractCallWrapper.args = { amount }; + return this; + } + + /** + * Sets the optional memo for the transfer + * + * @param memo + */ + public memo(memo: string): this { + this.contractCallWrapper.args = { memo }; + return this; + } + + public addStorageDeposit(input: StorageDepositInput): void { + const methodName = 'storage_deposit'; + assert(input.deposit, new BuildTransactionError('deposit is required before building storage deposit transfer')); + assert(input.gas, new BuildTransactionError('gas is required before building fungible token transfer')); + const args = input.accountId ? { account_id: input.accountId } : {}; + const action = NearAPI.transactions.functionCall(methodName, args, input.gas, input.deposit); + super.action(action); + } + + /** @inheritdoc */ + protected async buildImplementation(): Promise { + const { methodName, args, gas, deposit } = this.contractCallWrapper.getParams(); + assert(gas, new BuildTransactionError('gas is required before building fungible token transfer')); + assert(deposit, new BuildTransactionError('deposit is required before building fungible token transfer')); + + super.action(NearAPI.transactions.functionCall(methodName, args, BigInt(gas), BigInt(deposit))); + const tx = await super.buildImplementation(); + tx.setTransactionType(TransactionType.Send); + return tx; + } +} diff --git a/modules/sdk-coin-near/src/lib/iface.ts b/modules/sdk-coin-near/src/lib/iface.ts index bdb94de513..ac5fcf1c12 100644 --- a/modules/sdk-coin-near/src/lib/iface.ts +++ b/modules/sdk-coin-near/src/lib/iface.ts @@ -1,21 +1,17 @@ -import BN from 'bn.js'; +import { KeyType } from '@near-js/crypto'; import { TransactionType, TransactionExplanation as BaseTransactionExplanation } from '@bitgo/sdk-core'; export interface TransactionExplanation extends BaseTransactionExplanation { type: TransactionType; } -export enum KeyType { - ED25519 = 0, -} - export interface Signature { keyType: KeyType; data: Uint8Array; } export interface Transfer { - deposit: BN; + deposit: bigint; } /** Interface with parameters needed to perform FunctionCall to a contract */ @@ -38,9 +34,15 @@ export interface Action { export interface TxData { id?: string; signerId: string; - publicKey: string; - nonce: number; + publicKey?: string; + nonce: bigint; receiverId: string; actions: Action[]; signature?: Signature; } + +export interface StorageDepositInput { + deposit: bigint; + gas: bigint; + accountId?: string; +} diff --git a/modules/sdk-coin-near/src/lib/initializableBuilder.ts b/modules/sdk-coin-near/src/lib/initializableBuilder.ts new file mode 100644 index 0000000000..825d34380a --- /dev/null +++ b/modules/sdk-coin-near/src/lib/initializableBuilder.ts @@ -0,0 +1,6 @@ +import { DelegateTransaction } from './delegateTransaction'; +import { Transaction } from './transaction'; + +export interface InitializableBuilder { + initBuilder(tx: Transaction | DelegateTransaction): void; +} diff --git a/modules/sdk-coin-near/src/lib/stakingActivateBuilder.ts b/modules/sdk-coin-near/src/lib/stakingActivateBuilder.ts index 65617a0224..25fe86bbb8 100644 --- a/modules/sdk-coin-near/src/lib/stakingActivateBuilder.ts +++ b/modules/sdk-coin-near/src/lib/stakingActivateBuilder.ts @@ -4,7 +4,6 @@ import { Transaction } from './transaction'; import BigNumber from 'bignumber.js'; import * as NearAPI from 'near-api-js'; import assert from 'assert'; -import BN from 'bn.js'; import { ContractCallWrapper } from './contractCallWrapper'; import { TransactionBuilder } from './transactionBuilder'; @@ -32,14 +31,16 @@ export class StakingActivateBuilder extends TransactionBuilder { initBuilder(tx: Transaction): void { super.initBuilder(tx); const functionCall = tx.nearTransaction.actions[0].functionCall; - this.contractCallWrapper.deposit = functionCall.deposit.toString(); - this.contractCallWrapper.gas = functionCall.gas.toString(); + if (functionCall) { + this.contractCallWrapper.deposit = functionCall.deposit.toString(); + this.contractCallWrapper.gas = functionCall.gas.toString(); + } } /** * Sets the gas of this transaction. * - * @param {string} value the gas of this transaction + * @param {string} gas the gas of this transaction * @returns {TransactionBuilder} This transaction builder */ public gas(gas: string): this { @@ -51,7 +52,7 @@ export class StakingActivateBuilder extends TransactionBuilder { /** * Sets the amount of this transaction. * - * @param {string} value the amount in the minimum unit (1 Near = 1e24 yoctos) of this transaction + * @param {string} amount the amount in the minimum unit (1 Near = 1e24 yoctos) of this transaction * @returns {TransactionBuilder} This transaction builder */ public amount(amount: string): this { @@ -67,7 +68,7 @@ export class StakingActivateBuilder extends TransactionBuilder { assert(gas, new BuildTransactionError('gas is required before building staking activate')); assert(deposit, new BuildTransactionError('amount is required before building staking activate')); - super.actions([NearAPI.transactions.functionCall(methodName, args, new BN(gas), new BN(deposit, 10))]); + super.actions([NearAPI.transactions.functionCall(methodName, args, BigInt(gas), BigInt(deposit))]); const tx = await super.buildImplementation(); tx.setTransactionType(TransactionType.StakingActivate); return tx; diff --git a/modules/sdk-coin-near/src/lib/stakingDeactivateBuilder.ts b/modules/sdk-coin-near/src/lib/stakingDeactivateBuilder.ts index d3aa33eb74..6ce5e3e970 100644 --- a/modules/sdk-coin-near/src/lib/stakingDeactivateBuilder.ts +++ b/modules/sdk-coin-near/src/lib/stakingDeactivateBuilder.ts @@ -4,7 +4,6 @@ import { Transaction } from './transaction'; import BigNumber from 'bignumber.js'; import * as NearAPI from 'near-api-js'; import assert from 'assert'; -import BN from 'bn.js'; import { ContractCallWrapper } from './contractCallWrapper'; import { TransactionBuilder } from './transactionBuilder'; @@ -32,14 +31,16 @@ export class StakingDeactivateBuilder extends TransactionBuilder { initBuilder(tx: Transaction): void { super.initBuilder(tx); const functionCall = tx.nearTransaction.actions[0].functionCall; - this.contractCallWrapper.args = JSON.parse(Buffer.from(functionCall.args).toString()); - this.contractCallWrapper.gas = functionCall.gas.toString(); + if (functionCall) { + this.contractCallWrapper.args = JSON.parse(Buffer.from(functionCall.args).toString()); + this.contractCallWrapper.gas = functionCall.gas.toString(); + } } /** * Sets the gas of this transaction. * - * @param {string} value the gas of this transaction + * @param {string} gas the gas of this transaction * @returns {TransactionBuilder} This transaction builder */ public gas(gas: string): this { @@ -51,7 +52,7 @@ export class StakingDeactivateBuilder extends TransactionBuilder { /** * Sets the amount of this transaction. * - * @param {string} value the amount in the minimum unit (1 Near = 1e24 yoctos) of this transaction + * @param {string} amount the amount in the minimum unit (1 Near = 1e24 yoctos) of this transaction * @returns {TransactionBuilder} This transaction builder */ public amount(amount: string): this { @@ -66,7 +67,7 @@ export class StakingDeactivateBuilder extends TransactionBuilder { assert(gas, new BuildTransactionError('gas is required before building staking deactivate')); assert(args?.amount, new BuildTransactionError('amount is required before building staking deactivate')); - super.actions([NearAPI.transactions.functionCall(methodName, args, new BN(gas), new BN(deposit))]); + super.actions([NearAPI.transactions.functionCall(methodName, args, BigInt(gas), BigInt(deposit))]); const tx = await super.buildImplementation(); tx.setTransactionType(TransactionType.StakingDeactivate); return tx; diff --git a/modules/sdk-coin-near/src/lib/stakingWithdrawBuilder.ts b/modules/sdk-coin-near/src/lib/stakingWithdrawBuilder.ts index 96f1fac962..149c5b9f33 100644 --- a/modules/sdk-coin-near/src/lib/stakingWithdrawBuilder.ts +++ b/modules/sdk-coin-near/src/lib/stakingWithdrawBuilder.ts @@ -4,7 +4,6 @@ import { Transaction } from './transaction'; import BigNumber from 'bignumber.js'; import * as NearAPI from 'near-api-js'; import assert from 'assert'; -import BN from 'bn.js'; import { ContractCallWrapper } from './contractCallWrapper'; import { TransactionBuilder } from './transactionBuilder'; @@ -32,14 +31,16 @@ export class StakingWithdrawBuilder extends TransactionBuilder { initBuilder(tx: Transaction): void { super.initBuilder(tx); const functionCall = tx.nearTransaction.actions[0].functionCall; - this.contractCallWrapper.args = JSON.parse(Buffer.from(functionCall.args).toString()); - this.contractCallWrapper.gas = functionCall.gas.toString(); + if (functionCall) { + this.contractCallWrapper.args = JSON.parse(Buffer.from(functionCall.args).toString()); + this.contractCallWrapper.gas = functionCall.gas.toString(); + } } /** * Sets the gas of this transaction. * - * @param {string} value the gas of this transaction + * @param {string} gas the gas of this transaction * @returns {TransactionBuilder} This transaction builder */ public gas(gas: string): this { @@ -51,7 +52,7 @@ export class StakingWithdrawBuilder extends TransactionBuilder { /** * Sets the amount of this transaction. * - * @param {string} value the amount in the minimum unit (1 Near = 1e24 yoctos) of this transaction + * @param {string} amount the amount in the minimum unit (1 Near = 1e24 yoctos) of this transaction * @returns {TransactionBuilder} This transaction builder */ public amount(amount: string): this { @@ -66,7 +67,7 @@ export class StakingWithdrawBuilder extends TransactionBuilder { assert(gas, new BuildTransactionError('gas is required before building staking withdraw')); assert(args?.amount, new BuildTransactionError('amount is required before building staking withdraw')); - super.actions([NearAPI.transactions.functionCall(methodName, args, new BN(gas), new BN(deposit))]); + super.actions([NearAPI.transactions.functionCall(methodName, args, BigInt(gas), BigInt(deposit))]); const tx = await super.buildImplementation(); tx.setTransactionType(TransactionType.StakingWithdraw); return tx; diff --git a/modules/sdk-coin-near/src/lib/storageDepositTransferBuilder.ts b/modules/sdk-coin-near/src/lib/storageDepositTransferBuilder.ts new file mode 100644 index 0000000000..077ea9f522 --- /dev/null +++ b/modules/sdk-coin-near/src/lib/storageDepositTransferBuilder.ts @@ -0,0 +1,98 @@ +import assert from 'assert'; +import BigNumber from 'bignumber.js'; +import * as NearAPI from 'near-api-js'; + +import { BuildTransactionError, TransactionType } from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; + +import { AbstractDelegateBuilder } from './abstractDelegateBuilder'; +import { ContractCallWrapper } from './contractCallWrapper'; +import { DelegateTransaction } from './delegateTransaction'; +import { STORAGE_DEPOSIT } from './constants'; +import utils from './utils'; + +export class StorageDepositTransferBuilder extends AbstractDelegateBuilder { + private contractCallWrapper: ContractCallWrapper; + + constructor(_coinConfig: Readonly) { + super(_coinConfig); + this.contractCallWrapper = new ContractCallWrapper(); + this.contractCallWrapper.methodName = STORAGE_DEPOSIT; + } + + /** + * Initialize the transaction builder fields using the decoded transaction data + * + * @param {DelegateTransaction} tx the transaction data + */ + initBuilder(tx: DelegateTransaction): void { + super.initBuilder(tx); + for (const action of tx.nearTransaction.actions) { + if (action.functionCall && action.functionCall.methodName === STORAGE_DEPOSIT) { + this.contractCallWrapper.deposit = action.functionCall.deposit.toString(); + this.contractCallWrapper.gas = action.functionCall.gas.toString(); + } + } + } + + /** + * Sets the gas of this transaction. + * + * @param {String} gas the gas of this transaction + * @returns {TransactionBuilder} This transaction builder + */ + public gas(gas: string): this { + this.validateValue(new BigNumber(gas)); + this.contractCallWrapper.gas = gas; + return this; + } + + /** + * Sets the deposit of at-least 1 yoctoNear + * + * @param {string} deposit the deposit in the minimum unit (1 Near = 1e24 yoctoNear) of this transaction + * @returns {TransactionBuilder} This transaction builder + */ + public deposit(deposit: string): this { + this.validateValue(new BigNumber(deposit)); + this.contractCallWrapper.deposit = deposit; + return this; + } + + /** + * @inheritdoc + * + * We need to override this because for contract call the receiver id is the contract address + * And we need to pass the actual receiver id in the args + * + * @param accountId the contract address + */ + public receiverId(accountId: string): this { + utils.isValidAddress(accountId); + this._receiverId = accountId; + return this; + } + + /** + * Sets the actual receiver account id inside args + * + * @param accountId the receiver account id + */ + public beneficiaryId(accountId: string): this { + utils.isValidAddress(accountId); + this.contractCallWrapper.args = { account_id: accountId }; + return this; + } + + /** @inheritdoc */ + protected async buildImplementation(): Promise { + const { methodName, args, gas, deposit } = this.contractCallWrapper.getParams(); + assert(gas, new BuildTransactionError('gas is required before building fungible token transfer')); + assert(deposit, new BuildTransactionError('deposit is required before building fungible token transfer')); + + super.action(NearAPI.transactions.functionCall(methodName, args, BigInt(gas), BigInt(deposit))); + const tx = await super.buildImplementation(); + tx.setTransactionType(TransactionType.StorageDeposit); + return tx; + } +} diff --git a/modules/sdk-coin-near/src/lib/transaction.ts b/modules/sdk-coin-near/src/lib/transaction.ts index de7f55e413..33352439ff 100644 --- a/modules/sdk-coin-near/src/lib/transaction.ts +++ b/modules/sdk-coin-near/src/lib/transaction.ts @@ -1,3 +1,11 @@ +import base58 from 'bs58'; +import { sha256 } from 'js-sha256'; +import * as nearAPI from 'near-api-js'; +import { functionCall, transfer } from 'near-api-js/lib/transaction'; + +import { KeyType } from '@near-js/crypto'; +import { Action as TxAction, SignedTransaction, Transaction as UnsignedTransaction } from '@near-js/transactions'; + import { BaseKey, BaseTransaction, @@ -7,13 +15,11 @@ import { TransactionType, } from '@bitgo/sdk-core'; import { BaseCoin as CoinConfig } from '@bitgo/statics'; -import { TransactionExplanation, TxData, Action } from './iface'; -import { HEX_REGEX, StakingContractMethodNames } from './constants'; -import utils from './utils'; + +import { AdditionalAllowedMethods, FT_TRANSFER, HEX_REGEX, StakingContractMethodNames } from './constants'; +import { Action, Signature, TransactionExplanation, TxData } from './iface'; import { KeyPair } from './keyPair'; -import * as nearAPI from 'near-api-js'; -import * as sha256 from 'js-sha256'; -import base58 from 'bs58'; +import utils from './utils'; export class Transaction extends BaseTransaction { private _nearTransaction: nearAPI.transactions.Transaction; @@ -32,6 +38,31 @@ export class Transaction extends BaseTransaction { this._id = utils.base58Encode(this.getTransactionHash()); } + static fromSigned(coinConfig: Readonly, signedTx: SignedTransaction): Transaction { + const tx = new Transaction(coinConfig); + tx.initFromSigned(signedTx); + return tx; + } + + static fromUnsigned(coinConfig: Readonly, unsignedTx: UnsignedTransaction): Transaction { + const tx = new Transaction(coinConfig); + tx.initFromUnsigned(unsignedTx); + return tx; + } + + private initFromSigned(signedTx: SignedTransaction): void { + this._nearSignedTransaction = signedTx; + this._nearTransaction = signedTx.transaction; + this._id = utils.base58Encode(this.getTransactionHash()); + this.loadInputsAndOutputs(); + } + + private initFromUnsigned(unsignedTx: UnsignedTransaction): void { + this._nearTransaction = unsignedTx; + this._id = utils.base58Encode(this.getTransactionHash()); + this.loadInputsAndOutputs(); + } + /** @inheritdoc */ canSign(key: BaseKey): boolean { try { @@ -60,28 +91,43 @@ export class Transaction extends BaseTransaction { } let parsedAction: Action = {}; - if (this._nearTransaction.actions[0].enum === 'transfer') { - parsedAction = { transfer: this._nearTransaction.actions[0].transfer }; - } else if (this._nearTransaction.actions[0].enum === 'functionCall') { - const functionCallObject = this._nearTransaction.actions[0].functionCall; + const action = this._nearTransaction.actions[0]; + if (action.enum === 'transfer' && action.transfer) { + parsedAction = { transfer: action.transfer }; + } else if (action.enum === 'functionCall' && action.functionCall) { + const functionCall = action.functionCall; parsedAction = { functionCall: { - methodName: functionCallObject.methodName, - args: JSON.parse(Buffer.from(functionCallObject.args).toString()), - gas: functionCallObject.gas.toString(), - deposit: functionCallObject.deposit.toString(), + methodName: functionCall.methodName, + args: JSON.parse(Buffer.from(functionCall.args).toString()), + gas: functionCall.gas.toString(), + deposit: functionCall.deposit.toString(), }, }; } + let signature: Signature | undefined; + if (this._nearSignedTransaction?.signature?.ed25519Signature) { + signature = { + keyType: KeyType.ED25519, + data: new Uint8Array(this._nearSignedTransaction.signature.ed25519Signature.data), + }; + } + let publicKey: string | undefined; + if (this._nearTransaction.publicKey?.ed25519Key) { + const rawBytes = new Uint8Array(this._nearTransaction.publicKey.ed25519Key.data); + const encoded = nearAPI.utils.serialize.base_encode(rawBytes); + publicKey = `ed25519:${encoded}`; + } + return { id: this._id, signerId: this._nearTransaction.signerId, - publicKey: this._nearTransaction.publicKey.toString(), + publicKey: publicKey, nonce: this._nearTransaction.nonce, receiverId: this._nearTransaction.receiverId, actions: [parsedAction], - signature: typeof this._nearSignedTransaction === 'undefined' ? undefined : this._nearSignedTransaction.signature, + signature: signature ? signature : undefined, }; } @@ -103,22 +149,70 @@ export class Transaction extends BaseTransaction { const bufferRawTransaction = HEX_REGEX.test(rawTx) ? Buffer.from(rawTx, 'hex') : Buffer.from(rawTx, 'base64'); try { const signedTx = nearAPI.utils.serialize.deserialize( - nearAPI.transactions.SCHEMA, - nearAPI.transactions.SignedTransaction, + nearAPI.transactions.SCHEMA.SignedTransaction, bufferRawTransaction - ); - signedTx.transaction.nonce = parseInt(signedTx.transaction.nonce.toString(), 10); + ) as SignedTransaction; + signedTx.transaction.actions = signedTx.transaction.actions.map((a) => { + const action = new TxAction(a); + switch (action.enum) { + case 'transfer': { + if (action.transfer?.deposit) { + return transfer(BigInt(action.transfer.deposit)); + } + break; + } + case 'functionCall': { + if (action.functionCall) { + return functionCall( + action.functionCall.methodName, + new Uint8Array(action.functionCall.args), + BigInt(action.functionCall.gas), + BigInt(action.functionCall.deposit) + ); + } + break; + } + default: { + return action; + } + } + return action; + }); this._nearSignedTransaction = signedTx; this._nearTransaction = signedTx.transaction; this._id = utils.base58Encode(this.getTransactionHash()); } catch (e) { try { const unsignedTx = nearAPI.utils.serialize.deserialize( - nearAPI.transactions.SCHEMA, - nearAPI.transactions.Transaction, + nearAPI.transactions.SCHEMA.Transaction, bufferRawTransaction - ); - unsignedTx.nonce = parseInt(unsignedTx.nonce.toString(), 10); + ) as UnsignedTransaction; + unsignedTx.actions = unsignedTx.actions.map((a) => { + const action = new TxAction(a); + switch (action.enum) { + case 'transfer': { + if (action.transfer?.deposit) { + return transfer(BigInt(action.transfer.deposit)); + } + break; + } + case 'functionCall': { + if (action.functionCall) { + return functionCall( + action.functionCall.methodName, + new Uint8Array(action.functionCall.args), + BigInt(action.functionCall.gas), + BigInt(action.functionCall.deposit) + ); + } + break; + } + default: { + return action; + } + } + return action; + }); this._nearTransaction = unsignedTx; this._id = utils.base58Encode(this.getTransactionHash()); } catch (e) { @@ -166,16 +260,20 @@ export class Transaction extends BaseTransaction { case StakingContractMethodNames.Withdraw: this.setTransactionType(TransactionType.StakingWithdraw); break; + case FT_TRANSFER: + this.setTransactionType(TransactionType.SendToken); + break; } } /** * Check if method is allowed on Near account-lib implementation. * This method should check on all contracts added to Near. - * @param methodName contract call method name to check if its allowed. + * @param methodName contract call method name to check if it's allowed. */ private validateMethodAllowed(methodName: string): void { - if (!Object.values(StakingContractMethodNames).some((item) => item === methodName)) { + const allowedMethods = [...Object.values(StakingContractMethodNames), ...AdditionalAllowedMethods]; + if (!allowedMethods.includes(methodName)) { throw new InvalidTransactionError('unsupported function call in raw transaction'); } } @@ -196,9 +294,11 @@ export class Transaction extends BaseTransaction { this.setTransactionType(TransactionType.Send); break; case 'functionCall': - const methodName = action.functionCall.methodName; - this.validateMethodAllowed(methodName); - this.setTypeByStakingMethod(methodName); + if (action.functionCall) { + const methodName = action.functionCall.methodName; + this.validateMethodAllowed(methodName); + this.setTypeByStakingMethod(methodName); + } break; default: throw new InvalidTransactionError('unsupported action in raw transaction'); @@ -208,43 +308,65 @@ export class Transaction extends BaseTransaction { const inputs: Entry[] = []; switch (this.type) { case TransactionType.Send: - const amount = action.transfer.deposit.toString(); - inputs.push({ - address: this._nearTransaction.signerId, - value: amount, - coin: this._coinConfig.name, - }); - outputs.push({ - address: this._nearTransaction.receiverId, - value: amount, - coin: this._coinConfig.name, - }); + if (action.transfer) { + const amount = action.transfer.deposit.toString(); + inputs.push({ + address: this._nearTransaction.signerId, + value: amount, + coin: this._coinConfig.name, + }); + outputs.push({ + address: this._nearTransaction.receiverId, + value: amount, + coin: this._coinConfig.name, + }); + } break; case TransactionType.StakingActivate: - const stakingAmount = action.functionCall.deposit.toString(); - inputs.push({ - address: this._nearTransaction.signerId, - value: stakingAmount, - coin: this._coinConfig.name, - }); - outputs.push({ - address: this._nearTransaction.receiverId, - value: stakingAmount, - coin: this._coinConfig.name, - }); + if (action.functionCall) { + const stakingAmount = action.functionCall.deposit.toString(); + inputs.push({ + address: this._nearTransaction.signerId, + value: stakingAmount, + coin: this._coinConfig.name, + }); + outputs.push({ + address: this._nearTransaction.receiverId, + value: stakingAmount, + coin: this._coinConfig.name, + }); + } break; case TransactionType.StakingWithdraw: - const stakingWithdrawAmount = JSON.parse(Buffer.from(action.functionCall.args).toString()).amount; - inputs.push({ - address: this._nearTransaction.receiverId, - value: stakingWithdrawAmount, - coin: this._coinConfig.name, - }); - outputs.push({ - address: this._nearTransaction.signerId, - value: stakingWithdrawAmount, - coin: this._coinConfig.name, - }); + if (action.functionCall) { + const stakingWithdrawAmount = JSON.parse(Buffer.from(action.functionCall.args).toString()).amount; + inputs.push({ + address: this._nearTransaction.receiverId, + value: stakingWithdrawAmount, + coin: this._coinConfig.name, + }); + outputs.push({ + address: this._nearTransaction.signerId, + value: stakingWithdrawAmount, + coin: this._coinConfig.name, + }); + } + break; + case TransactionType.SendToken: + if (action.functionCall) { + const tokenTransferAmount = JSON.parse(Buffer.from(action.functionCall.args).toString()).amount; + const receiverId = JSON.parse(Buffer.from(action.functionCall.args).toString()).receiver_id; + inputs.push({ + address: receiverId, + value: tokenTransferAmount, + coin: this._coinConfig.name, + }); + outputs.push({ + address: this._nearTransaction.signerId, + value: tokenTransferAmount, + coin: this._coinConfig.name, + }); + } break; } this._outputs = outputs; @@ -340,8 +462,11 @@ export class Transaction extends BaseTransaction { } private getTransactionHash(): Uint8Array { - const serializedTx = nearAPI.utils.serialize.serialize(nearAPI.transactions.SCHEMA, this._nearTransaction); - return new Uint8Array(sha256.sha256.array(serializedTx)); + const serializedTx = nearAPI.utils.serialize.serialize( + nearAPI.transactions.SCHEMA.Transaction, + this._nearTransaction + ); + return new Uint8Array(sha256.array(serializedTx)); } get signablePayload(): Buffer { @@ -373,8 +498,8 @@ export class Transaction extends BaseTransaction { get signature(): string[] { const signatures: string[] = []; - if (this._nearSignedTransaction) { - signatures.push(base58.encode(this._nearSignedTransaction.signature.data)); + if (this._nearSignedTransaction && this._nearSignedTransaction.signature.ed25519Signature) { + signatures.push(base58.encode(this._nearSignedTransaction.signature.ed25519Signature.data)); } return signatures; diff --git a/modules/sdk-coin-near/src/lib/transactionBuilder.ts b/modules/sdk-coin-near/src/lib/transactionBuilder.ts index 6ad7969d9f..61a6edb08e 100644 --- a/modules/sdk-coin-near/src/lib/transactionBuilder.ts +++ b/modules/sdk-coin-near/src/lib/transactionBuilder.ts @@ -1,5 +1,8 @@ +import assert from 'assert'; import BigNumber from 'bignumber.js'; -import { BaseCoin as CoinConfig } from '@bitgo/statics'; +import * as hex from '@stablelib/hex'; +import * as nearAPI from 'near-api-js'; + import { BaseAddress, BaseKey, @@ -8,20 +11,21 @@ import { PublicKey as BasePublicKey, Signature, } from '@bitgo/sdk-core'; -import { Transaction } from './transaction'; -import * as nearAPI from 'near-api-js'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; + import { AddressValidationError } from './errors'; -import utils from './utils'; -import assert from 'assert'; +import { InitializableBuilder } from './initializableBuilder'; import { KeyPair } from './keyPair'; -import * as hex from '@stablelib/hex'; -export abstract class TransactionBuilder extends BaseTransactionBuilder { +import { Transaction } from './transaction'; +import utils from './utils'; + +export abstract class TransactionBuilder extends BaseTransactionBuilder implements InitializableBuilder { private _transaction: Transaction; private _sender: string; private _publicKey: string; - private _receiverId: string; - private _nonce: number; + protected _receiverId: string; + private _nonce: bigint; private _recentBlockHash: string; private _signer: KeyPair; private _signatures: Signature[] = []; // only support single sig for now @@ -43,8 +47,10 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { this._sender = nearTransaction.signerId; this._nonce = nearTransaction.nonce; this._receiverId = nearTransaction.receiverId; - this._publicKey = hex.encode(nearTransaction.publicKey.data); - this._recentBlockHash = nearAPI.utils.serialize.base_encode(nearTransaction.blockHash); + if (nearTransaction.publicKey.ed25519Key?.data) { + this._publicKey = hex.encode(nearTransaction.publicKey.ed25519Key.data); + } + this._recentBlockHash = nearAPI.utils.serialize.base_encode(new Uint8Array(nearTransaction.blockHash)); this._actions = nearTransaction.actions; } @@ -107,18 +113,10 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { /** @inheritdoc */ validateRawTransaction(rawTransaction: any): void { try { - nearAPI.utils.serialize.deserialize( - nearAPI.transactions.SCHEMA, - nearAPI.transactions.SignedTransaction, - rawTransaction - ); + nearAPI.utils.serialize.deserialize(nearAPI.transactions.SCHEMA.SignedTransaction, rawTransaction); } catch { try { - nearAPI.utils.serialize.deserialize( - nearAPI.transactions.SCHEMA, - nearAPI.transactions.Transaction, - rawTransaction - ); + nearAPI.utils.serialize.deserialize(nearAPI.transactions.SCHEMA.Transaction, rawTransaction); } catch { throw new BuildTransactionError('invalid raw transaction'); } @@ -177,10 +175,10 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { /** * Set the nonce * - * @param {number} nonce - number that can be only used once + * @param {bigint} nonce - number that can be only used once * @returns {TransactionBuilder} This transaction builder */ - public nonce(nonce: number): this { + public nonce(nonce: bigint): this { if (nonce < 0) { throw new BuildTransactionError(`Invalid nonce: ${nonce}`); } diff --git a/modules/sdk-coin-near/src/lib/transactionBuilderFactory.ts b/modules/sdk-coin-near/src/lib/transactionBuilderFactory.ts index b8f7dff6c7..d7f1baa406 100644 --- a/modules/sdk-coin-near/src/lib/transactionBuilderFactory.ts +++ b/modules/sdk-coin-near/src/lib/transactionBuilderFactory.ts @@ -1,12 +1,19 @@ -import { BaseCoin as CoinConfig } from '@bitgo/statics'; import { BaseTransactionBuilderFactory, InvalidTransactionError, TransactionType } from '@bitgo/sdk-core'; -import { TransferBuilder } from './transferBuilder'; -import { WalletInitializationBuilder } from './walletInitializationBuilder'; -import { TransactionBuilder } from './transactionBuilder'; -import { Transaction } from './transaction'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; + +import { AbstractDelegateBuilder } from './abstractDelegateBuilder'; +import { DelegateTransaction } from './delegateTransaction'; +import { FungibleTokenTransferBuilder } from './fungibleTokenTransferBuilder'; +import { InitializableBuilder } from './initializableBuilder'; import { StakingActivateBuilder } from './stakingActivateBuilder'; import { StakingDeactivateBuilder } from './stakingDeactivateBuilder'; import { StakingWithdrawBuilder } from './stakingWithdrawBuilder'; +import { StorageDepositTransferBuilder } from './storageDepositTransferBuilder'; +import { Transaction } from './transaction'; +import { TransactionBuilder } from './transactionBuilder'; +import { TransactionFactory } from './transactionFactory'; +import { TransferBuilder } from './transferBuilder'; +import { WalletInitializationBuilder } from './walletInitializationBuilder'; export class TransactionBuilderFactory extends BaseTransactionBuilderFactory { constructor(_coinConfig: Readonly) { @@ -14,21 +21,24 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory { } /** @inheritdoc */ - from(raw: string): TransactionBuilder { + from(raw: string): TransactionBuilder | AbstractDelegateBuilder { try { - const tx = new Transaction(this._coinConfig); - tx.fromRawTransaction(raw); + const tx = TransactionFactory.fromRawTransaction(raw, this._coinConfig); switch (tx.type) { case TransactionType.Send: - return this.getTransferBuilder(tx); + return this.getTransferBuilder(tx as Transaction); case TransactionType.WalletInitialization: - return this.getWalletInitializationBuilder(tx); + return this.getWalletInitializationBuilder(tx as Transaction); case TransactionType.StakingActivate: - return this.getStakingActivateBuilder(tx); + return this.getStakingActivateBuilder(tx as Transaction); case TransactionType.StakingDeactivate: - return this.getStakingDeactivateBuilder(tx); + return this.getStakingDeactivateBuilder(tx as Transaction); case TransactionType.StakingWithdraw: - return this.getStakingWithdrawBuilder(tx); + return this.getStakingWithdrawBuilder(tx as Transaction); + case TransactionType.SendToken: + return this.getFungibleTokenTransferBuilder(tx as DelegateTransaction); + case TransactionType.StorageDeposit: + return this.getStorageDepositTransferBuilder(tx as DelegateTransaction); default: throw new InvalidTransactionError('unsupported transaction'); } @@ -59,6 +69,14 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory { return TransactionBuilderFactory.initializeBuilder(tx, new StakingWithdrawBuilder(this._coinConfig)); } + getFungibleTokenTransferBuilder(tx?: DelegateTransaction): FungibleTokenTransferBuilder { + return TransactionBuilderFactory.initializeBuilder(tx, new FungibleTokenTransferBuilder(this._coinConfig)); + } + + getStorageDepositTransferBuilder(tx?: DelegateTransaction): StorageDepositTransferBuilder { + return TransactionBuilderFactory.initializeBuilder(tx, new StorageDepositTransferBuilder(this._coinConfig)); + } + /** * Initialize the builder with the given transaction * @@ -66,7 +84,10 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory { * @param {TransactionBuilder} builder - the builder to be initialized * @returns {TransactionBuilder} the builder initialized */ - private static initializeBuilder(tx: Transaction | undefined, builder: T): T { + private static initializeBuilder( + tx: Transaction | DelegateTransaction | undefined, + builder: T + ): T { if (tx) { builder.initBuilder(tx); } diff --git a/modules/sdk-coin-near/src/lib/transactionFactory.ts b/modules/sdk-coin-near/src/lib/transactionFactory.ts new file mode 100644 index 0000000000..e883c891c0 --- /dev/null +++ b/modules/sdk-coin-near/src/lib/transactionFactory.ts @@ -0,0 +1,110 @@ +import * as nearAPI from 'near-api-js'; +import { functionCall, transfer } from 'near-api-js/lib/transaction'; + +import { DelegateAction, SignedDelegate, SignedTransaction, Action as TxAction } from '@near-js/transactions'; +import { Transaction as UnsignedTransaction } from '@near-js/transactions/lib/esm/schema'; + +import { InvalidTransactionError } from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; + +import { HEX_REGEX } from './constants'; +import { DelegateTransaction } from './delegateTransaction'; +import { Transaction } from './transaction'; + +export class TransactionFactory { + /** + * Builds either near transaction or delegate transaction from raw txn data, throws error if data is invalid + * + * @param {String} rawTx the raw transaction data + * @param {CoinConfig} config the coin config + * @returns {Transaction|DelegateTransaction} returns a near transaction or near delegate transaction + */ + static fromRawTransaction(rawTx: string, config: Readonly): Transaction | DelegateTransaction { + const bufferRawTransaction = HEX_REGEX.test(rawTx) ? Buffer.from(rawTx, 'hex') : Buffer.from(rawTx, 'base64'); + try { + const signedTx = nearAPI.utils.serialize.deserialize( + nearAPI.transactions.SCHEMA.SignedTransaction, + bufferRawTransaction + ) as SignedTransaction; + signedTx.transaction.actions = signedTx.transaction.actions.map((a) => { + const action = new TxAction(a); + switch (action.enum) { + case 'transfer': { + if (action.transfer?.deposit) { + return transfer(BigInt(action.transfer.deposit)); + } + break; + } + case 'functionCall': { + if (action.functionCall) { + return functionCall( + action.functionCall.methodName, + new Uint8Array(action.functionCall.args), + BigInt(action.functionCall.gas), + BigInt(action.functionCall.deposit) + ); + } + break; + } + default: { + return action; + } + } + return action; + }); + return Transaction.fromSigned(config, signedTx); + } catch (e) { + try { + const unsignedTx = nearAPI.utils.serialize.deserialize( + nearAPI.transactions.SCHEMA.Transaction, + bufferRawTransaction + ) as UnsignedTransaction; + unsignedTx.actions = unsignedTx.actions.map((a) => { + const action = new TxAction(a); + switch (action.enum) { + case 'transfer': { + if (action.transfer?.deposit) { + return transfer(BigInt(action.transfer.deposit)); + } + break; + } + case 'functionCall': { + if (action.functionCall) { + return functionCall( + action.functionCall.methodName, + new Uint8Array(action.functionCall.args), + BigInt(action.functionCall.gas), + BigInt(action.functionCall.deposit) + ); + } + break; + } + default: { + return action; + } + } + return action; + }); + return Transaction.fromUnsigned(config, unsignedTx); + } catch (e) { + try { + const signedDelegateAction = nearAPI.utils.serialize.deserialize( + nearAPI.transactions.SCHEMA.SignedDelegate, + bufferRawTransaction + ) as SignedDelegate; + return DelegateTransaction.fromSigned(config, signedDelegateAction); + } catch (e) { + try { + const delegateAction = nearAPI.utils.serialize.deserialize( + nearAPI.transactions.SCHEMA.DelegateAction, + bufferRawTransaction + ) as DelegateAction; + return DelegateTransaction.fromUnsigned(config, delegateAction); + } catch (e) { + throw new InvalidTransactionError('unable to build transaction from raw'); + } + } + } + } + } +} diff --git a/modules/sdk-coin-near/src/lib/transferBuilder.ts b/modules/sdk-coin-near/src/lib/transferBuilder.ts index 24a04bf413..24220ae621 100644 --- a/modules/sdk-coin-near/src/lib/transferBuilder.ts +++ b/modules/sdk-coin-near/src/lib/transferBuilder.ts @@ -4,7 +4,6 @@ import { TransactionBuilder } from './transactionBuilder'; import { Transaction } from './transaction'; import * as NearAPI from 'near-api-js'; import assert from 'assert'; -import BN from 'bn.js'; import BigNumber from 'bignumber.js'; export class TransferBuilder extends TransactionBuilder { @@ -21,13 +20,15 @@ export class TransferBuilder extends TransactionBuilder { */ initBuilder(tx: Transaction): void { super.initBuilder(tx); - this._amount = tx.nearTransaction.actions[0].transfer.deposit.toString(); + if (tx.nearTransaction.actions[0].transfer) { + this._amount = tx.nearTransaction.actions[0].transfer.deposit.toString(); + } } /** @inheritdoc */ protected async buildImplementation(): Promise { assert(this._amount, new BuildTransactionError('amount is required before building transfer')); - super.actions([NearAPI.transactions.transfer(new BN(this._amount))]); + super.actions([NearAPI.transactions.transfer(BigInt(this._amount))]); const tx = await super.buildImplementation(); tx.setTransactionType(TransactionType.Send); return tx; diff --git a/modules/sdk-coin-near/src/lib/utils.ts b/modules/sdk-coin-near/src/lib/utils.ts index ca371799f0..0ff2914737 100644 --- a/modules/sdk-coin-near/src/lib/utils.ts +++ b/modules/sdk-coin-near/src/lib/utils.ts @@ -73,7 +73,7 @@ export class Utils implements BaseUtils { * * @param {string} value - string to be checked * @param {number} length - expected decoded length - * @return {boolean} if the string can decoded as base58 and match the expected length + * @return {boolean} if the string can be decoded as base58 and match the expected length */ isBase58(value: string, length: number): boolean { try { diff --git a/modules/sdk-coin-near/src/near.ts b/modules/sdk-coin-near/src/near.ts index 1d6fd0d439..4788113788 100644 --- a/modules/sdk-coin-near/src/near.ts +++ b/modules/sdk-coin-near/src/near.ts @@ -92,7 +92,7 @@ interface RecoveryOptions { } interface NearTxBuilderParamsFromNode { - nonce: number; + nonce: bigint; blockHash: string; } diff --git a/modules/sdk-coin-near/src/nep141Token.ts b/modules/sdk-coin-near/src/nep141Token.ts index 438aa9c7c2..1d86ec828a 100644 --- a/modules/sdk-coin-near/src/nep141Token.ts +++ b/modules/sdk-coin-near/src/nep141Token.ts @@ -16,9 +16,11 @@ export class Nep141Token extends Near { return (bitgo: BitGoBase) => new Nep141Token(bitgo, config); } - static createTokenConstructors(): NamedCoinConstructor[] { + static createTokenConstructors( + tokenConfig: Nep141TokenConfig[] = [...tokens.bitcoin.near.tokens, ...tokens.testnet.near.tokens] + ): NamedCoinConstructor[] { const tokensCtors: NamedCoinConstructor[] = []; - for (const token of [...tokens.bitcoin.near.tokens, ...tokens.testnet.near.tokens]) { + for (const token of tokenConfig) { const tokenConstructor = Nep141Token.createTokenConstructor(token); tokensCtors.push({ name: token.type, coinConstructor: tokenConstructor }); } diff --git a/modules/sdk-coin-near/test/resources/near.ts b/modules/sdk-coin-near/test/resources/near.ts index a787dc8701..3aafa399ae 100644 --- a/modules/sdk-coin-near/test/resources/near.ts +++ b/modules/sdk-coin-near/test/resources/near.ts @@ -47,6 +47,10 @@ export const blockHash = { block2: 'CvjrdzHQB1KystXqa4bDWcLbNRaVUcrLZ3PVnMqHKyiW', }; +export const blockHeight = { + height1: 199957663n, +}; + export const errorBlockHash = { block1: 'CDEwwp7TjjahErrorriSvX3457qZ5uF3TtgEZHj7o5ssKFNs9', block2: 'CvjrdzHQB1KystXqa4bDWcLbNRaVUcrLZ3PVnMqHKyiW', @@ -92,6 +96,18 @@ export const rawTx = { unsigned: 'QAAAADYxYjE4YzZkYzAyZGRjYWJkZWFjNTZjYjRmMjFhOTcxY2M0MWNjOTc2NDBmNmY4NWIwNzM0ODAwMDhjNTNhMGQAYbGMbcAt3KverFbLTyGpccxBzJdkD2+FsHNIAAjFOg0BAAAAAAAAABwAAABsYXZlbmRlcmZpdmUucG9vbC5mODYzOTczLm0wppNL00/j8LLRb+dQg6da599fp9XXZsr3QyxL4aKNJmABAAAAAggAAAB3aXRoZHJhdxQAAAB7ImFtb3VudCI6IjEwMDAwMDAifQDQmNSvcQAAAAAAAAAAAAAAAAAAAAAAAA==', }, + fungibleTokenTransfer: { + signed: + 'QAAAADYxYjE4YzZkYzAyZGRjYWJkZWFjNTZjYjRmMjFhOTcxY2M0MWNjOTc2NDBmNmY4NWIwNzM0ODAwMDhjNTNhMGQTAAAAZnQtdG5lcDI0ZHAudGVzdG5ldAEAAAACCwAAAGZ0X3RyYW5zZmVybwAAAHsicmVjZWl2ZXJfaWQiOiI5ZjdiMDY3NWRiNTlkMTliNGJkOWM4YzcyZWFhYmJhNzVhOTg2M2QwMmIzMDExNWI4YjNjM2NhNWMyMGYwMjU0IiwiYW1vdW50IjoiMTAwIiwibWVtbyI6InRlc3QifQDQmNSvcQAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAFx3rCwAAAAAAYbGMbcAt3KverFbLTyGpccxBzJdkD2+FsHNIAAjFOg0Ar1Gt5mGg5+TjopIl/yW615eBxSfzinEJtE8Y5b3RKvjUqMPzL72LgTHU5eix9DVTqEMWKzDgJJUwNFJ5PyVRCA==', + unsigned: + 'bgEAQEAAAAA2MWIxOGM2ZGMwMmRkY2FiZGVhYzU2Y2I0ZjIxYTk3MWNjNDFjYzk3NjQwZjZmODViMDczNDgwMDA4YzUzYTBkEwAAAGZ0LXRuZXAyNGRwLnRlc3RuZXQBAAAAAgsAAABmdF90cmFuc2Zlcm8AAAB7InJlY2VpdmVyX2lkIjoiOWY3YjA2NzVkYjU5ZDE5YjRiZDljOGM3MmVhYWJiYTc1YTk4NjNkMDJiMzAxMTViOGIzYzNjYTVjMjBmMDI1NCIsImFtb3VudCI6IjEwMCIsIm1lbW8iOiJ0ZXN0In0A0JjUr3EAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAABcd6wsAAAAAAGGxjG3ALdyr3qxWy08hqXHMQcyXZA9vhbBzSAAIxToN', + }, + storageDeposit: { + signed: + 'QAAAADYxYjE4YzZkYzAyZGRjYWJkZWFjNTZjYjRmMjFhOTcxY2M0MWNjOTc2NDBmNmY4NWIwNzM0ODAwMDhjNTNhMGQTAAAAZnQtdG5lcDI0ZHAudGVzdG5ldAEAAAACDwAAAHN0b3JhZ2VfZGVwb3NpdAIAAAB7fQDQmNSvcQAAAABIVjcZPMNDAAAAAAAAAAEAAAAAAAAAFx3rCwAAAAAAYbGMbcAt3KverFbLTyGpccxBzJdkD2+FsHNIAAjFOg0AS3MFiIJ5DxfRxMtELbfXk8EmCsPHazMZ5mW4Fqhm6Y7j+8g+3VB8cMqWxncbLqDHA4o0XIAX0iBGb4VjyUX9Cw==', + unsigned: + 'bgEAQEAAAAA2MWIxOGM2ZGMwMmRkY2FiZGVhYzU2Y2I0ZjIxYTk3MWNjNDFjYzk3NjQwZjZmODViMDczNDgwMDA4YzUzYTBkEwAAAGZ0LXRuZXAyNGRwLnRlc3RuZXQBAAAAAg8AAABzdG9yYWdlX2RlcG9zaXQCAAAAe30A0JjUr3EAAAAASFY3GTzDQwAAAAAAAAABAAAAAAAAABcd6wsAAAAAAGGxjG3ALdyr3qxWy08hqXHMQcyXZA9vhbBzSAAIxToN', + }, }; export const AMOUNT = '1000000000000000000000000'; diff --git a/modules/sdk-coin-near/test/unit/keyPair.ts b/modules/sdk-coin-near/test/unit/keyPair.ts index f643ccc4f5..2f11acafa0 100644 --- a/modules/sdk-coin-near/test/unit/keyPair.ts +++ b/modules/sdk-coin-near/test/unit/keyPair.ts @@ -52,14 +52,14 @@ describe('NEAR KeyPair', () => { const source = { pub: '01D63D', }; - assert.throws(() => new KeyPair(source), /Non-base58 character/); + assert.throws(() => new KeyPair(source), /Unknown letter/); }); it('should fail to create from an invalid private key', () => { const source = { prv: '82A34', }; - assert.throws(() => new KeyPair(source), /Non-base58 character/); + assert.throws(() => new KeyPair(source), /Unknown letter/); }); }); diff --git a/modules/sdk-coin-near/test/unit/near.ts b/modules/sdk-coin-near/test/unit/near.ts index 83bd505223..48692cc140 100644 --- a/modules/sdk-coin-near/test/unit/near.ts +++ b/modules/sdk-coin-near/test/unit/near.ts @@ -273,7 +273,7 @@ describe('NEAR:', function () { .sender(accounts.account1.address, accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: accounts.account1.secretKey }); const tx = await txBuilder.build(); const txToBroadcastFormat = tx.toBroadcastFormat(); @@ -300,7 +300,7 @@ describe('NEAR:', function () { .sender(accounts.account1.address, accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: accounts.account1.secretKey }); const tx = await txBuilder.build(); const txToBroadcastFormat = tx.toBroadcastFormat(); @@ -322,7 +322,7 @@ describe('NEAR:', function () { .sender(accounts.account1.address, accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: accounts.account1.secretKey }); const tx = await txBuilder.build(); const txToBroadcastFormat = tx.toBroadcastFormat(); @@ -404,7 +404,7 @@ describe('NEAR:', function () { .sender(accounts.account1.address, accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: accounts.account1.secretKey }); const tx = await txBuilder.build(); const txToBroadcastFormat = tx.toBroadcastFormat(); @@ -440,7 +440,7 @@ describe('NEAR:', function () { .sender(accounts.account1.address, accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: accounts.account1.secretKey }); const tx = await txBuilder.build(); const txToBroadcastFormat = tx.toBroadcastFormat(); @@ -471,7 +471,7 @@ describe('NEAR:', function () { .sender(accounts.account1.address, accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: accounts.account1.secretKey }); const tx = await txBuilder.build(); const txToBroadcastFormat = tx.toBroadcastFormat(); @@ -600,7 +600,7 @@ describe('NEAR:', function () { .sender(accounts.account1.address, accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: accounts.account1.secretKey }); const tx = await txBuilder.build(); const txToBroadcastFormat = tx.toBroadcastFormat(); @@ -624,7 +624,7 @@ describe('NEAR:', function () { .sender(accounts.account1.address, accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: accounts.account1.secretKey }); const tx = await txBuilder.build(); const txToBroadcastFormat = tx.toBroadcastFormat(); @@ -648,7 +648,7 @@ describe('NEAR:', function () { .sender(accounts.account1.address, accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: accounts.account1.secretKey }); const tx = await txBuilder.build(); const txToBroadcastFormat = tx.toBroadcastFormat(); diff --git a/modules/sdk-coin-near/test/unit/transactionBuilder/fungibleTokenTransferBuilder.ts b/modules/sdk-coin-near/test/unit/transactionBuilder/fungibleTokenTransferBuilder.ts new file mode 100644 index 0000000000..7ee60f610c --- /dev/null +++ b/modules/sdk-coin-near/test/unit/transactionBuilder/fungibleTokenTransferBuilder.ts @@ -0,0 +1,212 @@ +import should from 'should'; +import * as base58 from 'bs58'; + +import { BitGoAPI } from '@bitgo/sdk-api'; +import { Eddsa, TransactionType } from '@bitgo/sdk-core'; +import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test'; +import { coins } from '@bitgo/statics'; + +import * as testData from '../../resources/near'; +import { getBuilderFactory } from '../getBuilderFactory'; + +import { KeyPair, Nep141Token, TransactionBuilderFactory } from '../../../src'; +import { StorageDepositInput } from '../../../src/lib/iface'; + +describe('Near: Fungible Token Transfer Builder', () => { + const coinName = 'near:usdc'; + const coinNameTest = 'tnear:tnep24dp'; + let nep141Token: Nep141Token; + let bitgo: TestBitGoAPI; + + before(function () { + bitgo = TestBitGo.decorate(BitGoAPI, { + env: 'mock', + }); + bitgo.initializeTestVars(); + Nep141Token.createTokenConstructors().forEach(({ name, coinConstructor }) => { + bitgo.safeRegister(name, coinConstructor); + }); + nep141Token = bitgo.coin(coinNameTest) as Nep141Token; + }); + + describe('Near fungible token transfer builder', function () { + const factory = new TransactionBuilderFactory(coins.get(coinNameTest)); + const factoryProd = new TransactionBuilderFactory(coins.get(coinName)); + const gas = '125000000000000'; + const deposit = '1'; + + const initTxBuilder = () => { + const txBuilder = factory.getFungibleTokenTransferBuilder(); + txBuilder.gas(gas); + txBuilder.deposit(deposit); + txBuilder.ftReceiverId(testData.accounts.account2.address); + txBuilder.amount('100'); + txBuilder.memo('test'); + txBuilder.nonce(BigInt(1)); + txBuilder.receiverId(nep141Token.contractAddress); + txBuilder.recentBlockHeight(testData.blockHeight.height1); + return txBuilder; + }; + + describe('fungible token builder environment', function () { + it('should select the right network', function () { + should.equal(factory.getFungibleTokenTransferBuilder().coinName(), coinNameTest); + should.equal(factoryProd.getFungibleTokenTransferBuilder().coinName(), coinName); + // used type any to access protected properties + const txBuilder: any = factory.getFungibleTokenTransferBuilder(); + const txBuilderProd: any = factoryProd.getFungibleTokenTransferBuilder(); + + txBuilder._coinConfig.name.should.deepEqual(coinNameTest); + txBuilderProd._coinConfig.name.should.deepEqual(coinName); + }); + }); + + describe('should build', function () { + it('an unsigned fungible token transfer transaction', async () => { + const builder = initTxBuilder(); + builder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); + const tx = await builder.build(); + should.equal(tx.type, TransactionType.Send); + tx.inputs.length.should.equal(1); + tx.inputs[0].should.deepEqual({ + address: testData.accounts.account2.address, + value: '100', + coin: coinNameTest, + }); + tx.outputs.length.should.equal(1); + tx.outputs[0].should.deepEqual({ + address: testData.accounts.account1.address, + value: '100', + coin: coinNameTest, + }); + const rawTx = tx.toBroadcastFormat(); + rawTx.should.deepEqual(testData.rawTx.fungibleTokenTransfer.unsigned); + }); + + it('a signed fungible token transfer transaction', async () => { + const builder = initTxBuilder(); + builder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); + builder.sign({ key: testData.accounts.account1.secretKey }); + const tx = await builder.build(); + should.equal(tx.type, TransactionType.Send); + tx.inputs.length.should.equal(1); + tx.inputs[0].should.deepEqual({ + address: testData.accounts.account2.address, + value: '100', + coin: coinNameTest, + }); + tx.outputs.length.should.equal(1); + tx.outputs[0].should.deepEqual({ + address: testData.accounts.account1.address, + value: '100', + coin: coinNameTest, + }); + const rawTx = tx.toBroadcastFormat(); + rawTx.should.deepEqual(testData.rawTx.fungibleTokenTransfer.signed); + }); + }); + + it('an unsigned fungible token transfer with storage deposit transaction', async () => { + const builder = initTxBuilder(); + builder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); + const storageDepositInput: StorageDepositInput = { + deposit: BigInt('1250000000000000000000'), + gas: BigInt(125000000000000), + }; + builder.addStorageDeposit(storageDepositInput); + const tx = await builder.build(); + should.equal(tx.type, TransactionType.Send); + tx.inputs.length.should.equal(2); + tx.outputs.length.should.equal(2); + }); + + it('a signed fungible token transfer with storage deposit transaction', async () => { + const builder = initTxBuilder(); + builder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); + const storageDepositInput: StorageDepositInput = { + deposit: BigInt('1250000000000000000000'), + gas: BigInt(125000000000000), + }; + builder.addStorageDeposit(storageDepositInput); + builder.sign({ key: testData.accounts.account1.secretKey }); + const tx = await builder.build(); + should.equal(tx.type, TransactionType.Send); + tx.inputs.length.should.equal(2); + tx.outputs.length.should.equal(2); + }); + + describe('add TSS signature', function () { + let MPC: Eddsa; + + before('initialize mpc module', async () => { + MPC = await Eddsa.initialize(); + }); + it('should add TSS signature', async () => { + const factory = getBuilderFactory(coinNameTest); + const A = MPC.keyShare(1, 2, 3); + const B = MPC.keyShare(2, 2, 3); + const C = MPC.keyShare(3, 2, 3); + + const A_combine = MPC.keyCombine(A.uShare, [B.yShares[1], C.yShares[1]]); + const B_combine = MPC.keyCombine(B.uShare, [A.yShares[2], C.yShares[2]]); + const C_combine = MPC.keyCombine(C.uShare, [A.yShares[3], B.yShares[3]]); + + const commonPub = A_combine.pShare.y; + const nearKeyPair = new KeyPair({ pub: commonPub }); + const sender = nearKeyPair.getAddress(); + + let txBuilder = initTxBuilder(); + txBuilder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); + const unsignedTransaction = await txBuilder.build(); + const signablePayload = unsignedTransaction.signablePayload; + + // signing with A and B + let A_sign_share = MPC.signShare(signablePayload, A_combine.pShare, [A_combine.jShares[2]]); + let B_sign_share = MPC.signShare(signablePayload, B_combine.pShare, [B_combine.jShares[1]]); + let A_sign = MPC.sign(signablePayload, A_sign_share.xShare, [B_sign_share.rShares[1]], [C.yShares[1]]); + let B_sign = MPC.sign(signablePayload, B_sign_share.xShare, [A_sign_share.rShares[2]], [C.yShares[2]]); + // sign the message_buffer (unsigned txHex) + let signature = MPC.signCombine([A_sign, B_sign]); + let rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]); + txBuilder = initTxBuilder(); + txBuilder.sender(sender, commonPub); + txBuilder.addSignature({ pub: nearKeyPair.getKeys().pub }, rawSignature); + let signedTransaction = await txBuilder.build(); + signedTransaction.signature.length.should.equal(1); + signedTransaction.signature[0].should.equal(base58.encode(rawSignature)); + + // signing with A and C + A_sign_share = MPC.signShare(signablePayload, A_combine.pShare, [A_combine.jShares[3]]); + let C_sign_share = MPC.signShare(signablePayload, C_combine.pShare, [C_combine.jShares[1]]); + A_sign = MPC.sign(signablePayload, A_sign_share.xShare, [C_sign_share.rShares[1]], [B.yShares[1]]); + let C_sign = MPC.sign(signablePayload, C_sign_share.xShare, [A_sign_share.rShares[3]], [B.yShares[3]]); + signature = MPC.signCombine([A_sign, C_sign]); + rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]); + txBuilder = initTxBuilder(); + txBuilder.sender(sender, commonPub); + txBuilder.addSignature({ pub: nearKeyPair.getKeys().pub }, rawSignature); + signedTransaction = await txBuilder.build(); + signedTransaction.signature.length.should.equal(1); + signedTransaction.signature[0].should.equal(base58.encode(rawSignature)); + + // signing with B and C + B_sign_share = MPC.signShare(signablePayload, B_combine.pShare, [B_combine.jShares[3]]); + C_sign_share = MPC.signShare(signablePayload, C_combine.pShare, [C_combine.jShares[2]]); + B_sign = MPC.sign(signablePayload, B_sign_share.xShare, [C_sign_share.rShares[2]], [A.yShares[2]]); + C_sign = MPC.sign(signablePayload, C_sign_share.xShare, [B_sign_share.rShares[3]], [A.yShares[3]]); + signature = MPC.signCombine([B_sign, C_sign]); + rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]); + txBuilder = initTxBuilder(); + txBuilder.sender(sender, commonPub); + txBuilder.addSignature({ pub: nearKeyPair.getKeys().pub }, rawSignature); + signedTransaction = await txBuilder.build(); + signedTransaction.signature.length.should.equal(1); + signedTransaction.signature[0].should.equal(base58.encode(rawSignature)); + + const rebuiltTransaction = await factory.from(signedTransaction.toBroadcastFormat()).build(); + + rebuiltTransaction.signature[0].should.equal(base58.encode(rawSignature)); + }); + }); + }); +}); diff --git a/modules/sdk-coin-near/test/unit/transactionBuilder/stakingActivateBuilder.ts b/modules/sdk-coin-near/test/unit/transactionBuilder/stakingActivateBuilder.ts index 4c6c8918e8..2657a42306 100644 --- a/modules/sdk-coin-near/test/unit/transactionBuilder/stakingActivateBuilder.ts +++ b/modules/sdk-coin-near/test/unit/transactionBuilder/stakingActivateBuilder.ts @@ -19,7 +19,7 @@ describe('Near Staking Activate Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: testData.accounts.account1.secretKey }); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); @@ -43,7 +43,7 @@ describe('Near Staking Activate Builder', () => { txJson.id.should.equal('GpiLLaGs2Fk2bd7SQvhkJaZjj74UnPPdF7cUa9pw15je'); txJson.signerId.should.equal(testData.accounts.account1.address); txJson.publicKey.should.equal(testData.accounts.account1.publicKeyBase58); - txJson.nonce.should.equal(1); + txJson.nonce.should.equal(BigInt(1)); txJson.receiverId.should.equal('lavenderfive.pool.f863973.m0'); txJson.actions.should.deepEqual([ { @@ -65,7 +65,7 @@ describe('Near Staking Activate Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); tx.inputs[0].should.deepEqual({ @@ -92,7 +92,7 @@ describe('Near Staking Activate Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); await txBuilder.build().should.be.rejectedWith('gas is required before building staking activate'); }); @@ -103,7 +103,7 @@ describe('Near Staking Activate Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); await txBuilder.build().should.be.rejectedWith('amount is required before building staking activate'); }); @@ -146,7 +146,7 @@ describe('Near Staking Activate Builder', () => { txJson.id.should.equal('GpiLLaGs2Fk2bd7SQvhkJaZjj74UnPPdF7cUa9pw15je'); txJson.signerId.should.equal(testData.accounts.account1.address); txJson.publicKey.should.equal(testData.accounts.account1.publicKeyBase58); - txJson.nonce.should.equal(1); + txJson.nonce.should.equal(BigInt(1)); txJson.receiverId.should.equal('lavenderfive.pool.f863973.m0'); txJson.actions.should.deepEqual([ { diff --git a/modules/sdk-coin-near/test/unit/transactionBuilder/stakingDeactivateBuilder.ts b/modules/sdk-coin-near/test/unit/transactionBuilder/stakingDeactivateBuilder.ts index 544416ad35..ed0db9d633 100644 --- a/modules/sdk-coin-near/test/unit/transactionBuilder/stakingDeactivateBuilder.ts +++ b/modules/sdk-coin-near/test/unit/transactionBuilder/stakingDeactivateBuilder.ts @@ -18,7 +18,7 @@ describe('Near Staking Deactivate Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: testData.accounts.account1.secretKey }); const tx = await txBuilder.build(); tx.inputs.length.should.equal(0); @@ -30,7 +30,7 @@ describe('Near Staking Deactivate Builder', () => { txJson.id.should.equal('CDxPRP3DgHN8gYmRDagk5TRuX7fsCRYHcuqoNULyQPUW'); txJson.signerId.should.equal(testData.accounts.account1.address); txJson.publicKey.should.equal(testData.accounts.account1.publicKeyBase58); - txJson.nonce.should.equal(1); + txJson.nonce.should.equal(BigInt(1)); txJson.receiverId.should.equal('lavenderfive.pool.f863973.m0'); txJson.actions.should.deepEqual([ { @@ -52,7 +52,7 @@ describe('Near Staking Deactivate Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); const tx = await txBuilder.build(); tx.inputs.length.should.equal(0); should.equal(tx.type, TransactionType.StakingDeactivate); @@ -67,7 +67,7 @@ describe('Near Staking Deactivate Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); await txBuilder.build().should.be.rejectedWith('gas is required before building staking deactivate'); }); @@ -78,7 +78,7 @@ describe('Near Staking Deactivate Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); await txBuilder.build().should.be.rejectedWith('amount is required before building staking deactivate'); }); @@ -90,7 +90,7 @@ describe('Near Staking Deactivate Builder', () => { txJson.id.should.equal('CDxPRP3DgHN8gYmRDagk5TRuX7fsCRYHcuqoNULyQPUW'); txJson.signerId.should.equal(testData.accounts.account1.address); txJson.publicKey.should.equal(testData.accounts.account1.publicKeyBase58); - txJson.nonce.should.equal(1); + txJson.nonce.should.equal(BigInt(1)); txJson.receiverId.should.equal('lavenderfive.pool.f863973.m0'); txJson.actions.should.deepEqual([ { @@ -112,7 +112,7 @@ describe('Near Staking Deactivate Builder', () => { txJson.id.should.equal('CDxPRP3DgHN8gYmRDagk5TRuX7fsCRYHcuqoNULyQPUW'); txJson.signerId.should.equal(testData.accounts.account1.address); txJson.publicKey.should.equal(testData.accounts.account1.publicKeyBase58); - txJson.nonce.should.equal(1); + txJson.nonce.should.equal(BigInt(1)); txJson.receiverId.should.equal('lavenderfive.pool.f863973.m0'); txJson.actions.should.deepEqual([ { diff --git a/modules/sdk-coin-near/test/unit/transactionBuilder/stakingWithdrawBuilder.ts b/modules/sdk-coin-near/test/unit/transactionBuilder/stakingWithdrawBuilder.ts index 6209f6d365..af6b7cc55b 100644 --- a/modules/sdk-coin-near/test/unit/transactionBuilder/stakingWithdrawBuilder.ts +++ b/modules/sdk-coin-near/test/unit/transactionBuilder/stakingWithdrawBuilder.ts @@ -18,7 +18,7 @@ describe('Near Staking withdraw Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); txBuilder.sign({ key: testData.accounts.account1.secretKey }); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); @@ -30,7 +30,7 @@ describe('Near Staking withdraw Builder', () => { txJson.id.should.equal('52ZX8MUwmYc6WQ67riUBpmntkcSxxT5aKkJYt5CtCZub'); txJson.signerId.should.equal(testData.accounts.account1.address); txJson.publicKey.should.equal(testData.accounts.account1.publicKeyBase58); - txJson.nonce.should.equal(1); + txJson.nonce.should.equal(BigInt(1)); txJson.receiverId.should.equal('lavenderfive.pool.f863973.m0'); txJson.actions.should.deepEqual([ { @@ -52,7 +52,7 @@ describe('Near Staking withdraw Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); should.equal(tx.type, TransactionType.StakingWithdraw); @@ -72,7 +72,7 @@ describe('Near Staking withdraw Builder', () => { txJson.id.should.equal('52ZX8MUwmYc6WQ67riUBpmntkcSxxT5aKkJYt5CtCZub'); txJson.signerId.should.equal(testData.accounts.account1.address); txJson.publicKey.should.equal(testData.accounts.account1.publicKeyBase58); - txJson.nonce.should.equal(1); + txJson.nonce.should.equal(BigInt(1)); txJson.receiverId.should.equal('lavenderfive.pool.f863973.m0'); txJson.actions.should.deepEqual([ { @@ -94,7 +94,7 @@ describe('Near Staking withdraw Builder', () => { txJson.id.should.equal('52ZX8MUwmYc6WQ67riUBpmntkcSxxT5aKkJYt5CtCZub'); txJson.signerId.should.equal(testData.accounts.account1.address); txJson.publicKey.should.equal(testData.accounts.account1.publicKeyBase58); - txJson.nonce.should.equal(1); + txJson.nonce.should.equal(BigInt(1)); txJson.receiverId.should.equal('lavenderfive.pool.f863973.m0'); txJson.actions.should.deepEqual([ { @@ -117,7 +117,7 @@ describe('Near Staking withdraw Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); await txBuilder.build().should.be.rejectedWith('gas is required before building staking withdraw'); }); @@ -128,7 +128,7 @@ describe('Near Staking withdraw Builder', () => { .sender(testData.accounts.account1.address, testData.accounts.account1.publicKey) .receiverId(validatorContractAddress) .recentBlockHash(testData.blockHash.block1) - .nonce(1); + .nonce(BigInt(1)); await txBuilder.build().should.be.rejectedWith('amount is required before building staking withdraw'); }); }); diff --git a/modules/sdk-coin-near/test/unit/transactionBuilder/storageDepositTransferBuilder.ts b/modules/sdk-coin-near/test/unit/transactionBuilder/storageDepositTransferBuilder.ts new file mode 100644 index 0000000000..b156bd6f7b --- /dev/null +++ b/modules/sdk-coin-near/test/unit/transactionBuilder/storageDepositTransferBuilder.ts @@ -0,0 +1,200 @@ +import should from 'should'; +import * as base58 from 'bs58'; + +import { BitGoAPI } from '@bitgo/sdk-api'; +import { Eddsa, TransactionType } from '@bitgo/sdk-core'; +import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test'; +import { coins } from '@bitgo/statics'; + +import * as testData from '../../resources/near'; +import { getBuilderFactory } from '../getBuilderFactory'; + +import { KeyPair, Nep141Token, TransactionBuilderFactory } from '../../../src'; + +describe('Near: Storage Deposit Transfer Builder', () => { + const coinName = 'near:usdc'; + const coinNameTest = 'tnear:tnep24dp'; + let nep141Token: Nep141Token; + let bitgo: TestBitGoAPI; + + before(function () { + bitgo = TestBitGo.decorate(BitGoAPI, { + env: 'mock', + }); + bitgo.initializeTestVars(); + Nep141Token.createTokenConstructors().forEach(({ name, coinConstructor }) => { + bitgo.safeRegister(name, coinConstructor); + }); + nep141Token = bitgo.coin(coinNameTest) as Nep141Token; + }); + + describe('Near storage deposit transfer builder', function () { + const factory = new TransactionBuilderFactory(coins.get(coinNameTest)); + const factoryProd = new TransactionBuilderFactory(coins.get(coinName)); + const gas = '125000000000000'; + const deposit = '1250000000000000000000'; + + const initTxBuilder = () => { + const txBuilder = factory.getStorageDepositTransferBuilder(); + txBuilder.gas(gas); + txBuilder.deposit(deposit); + txBuilder.nonce(BigInt(1)); + txBuilder.receiverId(nep141Token.contractAddress); + txBuilder.recentBlockHeight(testData.blockHeight.height1); + return txBuilder; + }; + + describe('fungible token builder environment', function () { + it('should select the right network', function () { + should.equal(factory.getStorageDepositTransferBuilder().coinName(), coinNameTest); + should.equal(factoryProd.getStorageDepositTransferBuilder().coinName(), coinName); + // used type any to access protected properties + const txBuilder: any = factory.getStorageDepositTransferBuilder(); + const txBuilderProd: any = factoryProd.getStorageDepositTransferBuilder(); + + txBuilder._coinConfig.name.should.deepEqual(coinNameTest); + txBuilderProd._coinConfig.name.should.deepEqual(coinName); + }); + }); + + describe('should build', function () { + it('an unsigned storage deposit self transfer transaction', async () => { + const builder = initTxBuilder(); + builder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); + const tx = await builder.build(); + should.equal(tx.type, TransactionType.StorageDeposit); + tx.inputs.length.should.equal(1); + tx.inputs[0].should.deepEqual({ + address: testData.accounts.account1.address, + value: '1250000000000000000000', + coin: nep141Token.getFamily(), + }); + tx.outputs.length.should.equal(1); + tx.outputs[0].should.deepEqual({ + address: testData.accounts.account1.address, + value: '1250000000000000000000', + coin: nep141Token.getFamily(), + }); + const rawTx = tx.toBroadcastFormat(); + rawTx.should.deepEqual(testData.rawTx.storageDeposit.unsigned); + }); + + it('a signed storage deposit self transfer transaction', async () => { + const builder = initTxBuilder(); + builder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); + builder.sign({ key: testData.accounts.account1.secretKey }); + const tx = await builder.build(); + should.equal(tx.type, TransactionType.StorageDeposit); + tx.inputs.length.should.equal(1); + tx.inputs[0].should.deepEqual({ + address: testData.accounts.account1.address, + value: '1250000000000000000000', + coin: nep141Token.getFamily(), + }); + tx.outputs.length.should.equal(1); + tx.outputs[0].should.deepEqual({ + address: testData.accounts.account1.address, + value: '1250000000000000000000', + coin: nep141Token.getFamily(), + }); + const rawTx = tx.toBroadcastFormat(); + rawTx.should.deepEqual(testData.rawTx.storageDeposit.signed); + }); + }); + + it('an unsigned storage deposit transfer transaction', async () => { + const builder = initTxBuilder(); + builder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); + builder.beneficiaryId(testData.accounts.account2.address); + const tx = await builder.build(); + should.equal(tx.type, TransactionType.StorageDeposit); + tx.inputs.length.should.equal(1); + tx.outputs.length.should.equal(1); + }); + + it('a signed fungible token transfer with storage deposit transaction', async () => { + const builder = initTxBuilder(); + builder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); + builder.beneficiaryId(testData.accounts.account2.address); + builder.sign({ key: testData.accounts.account1.secretKey }); + const tx = await builder.build(); + should.equal(tx.type, TransactionType.StorageDeposit); + tx.inputs.length.should.equal(1); + tx.outputs.length.should.equal(1); + }); + + describe('add TSS signature', function () { + let MPC: Eddsa; + + before('initialize mpc module', async () => { + MPC = await Eddsa.initialize(); + }); + it('should add TSS signature', async () => { + const factory = getBuilderFactory(coinNameTest); + const A = MPC.keyShare(1, 2, 3); + const B = MPC.keyShare(2, 2, 3); + const C = MPC.keyShare(3, 2, 3); + + const A_combine = MPC.keyCombine(A.uShare, [B.yShares[1], C.yShares[1]]); + const B_combine = MPC.keyCombine(B.uShare, [A.yShares[2], C.yShares[2]]); + const C_combine = MPC.keyCombine(C.uShare, [A.yShares[3], B.yShares[3]]); + + const commonPub = A_combine.pShare.y; + const nearKeyPair = new KeyPair({ pub: commonPub }); + const sender = nearKeyPair.getAddress(); + + let txBuilder = initTxBuilder(); + txBuilder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); + const unsignedTransaction = await txBuilder.build(); + const signablePayload = unsignedTransaction.signablePayload; + + // signing with A and B + let A_sign_share = MPC.signShare(signablePayload, A_combine.pShare, [A_combine.jShares[2]]); + let B_sign_share = MPC.signShare(signablePayload, B_combine.pShare, [B_combine.jShares[1]]); + let A_sign = MPC.sign(signablePayload, A_sign_share.xShare, [B_sign_share.rShares[1]], [C.yShares[1]]); + let B_sign = MPC.sign(signablePayload, B_sign_share.xShare, [A_sign_share.rShares[2]], [C.yShares[2]]); + // sign the message_buffer (unsigned txHex) + let signature = MPC.signCombine([A_sign, B_sign]); + let rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]); + txBuilder = initTxBuilder(); + txBuilder.sender(sender, commonPub); + txBuilder.addSignature({ pub: nearKeyPair.getKeys().pub }, rawSignature); + let signedTransaction = await txBuilder.build(); + signedTransaction.signature.length.should.equal(1); + signedTransaction.signature[0].should.equal(base58.encode(rawSignature)); + + // signing with A and C + A_sign_share = MPC.signShare(signablePayload, A_combine.pShare, [A_combine.jShares[3]]); + let C_sign_share = MPC.signShare(signablePayload, C_combine.pShare, [C_combine.jShares[1]]); + A_sign = MPC.sign(signablePayload, A_sign_share.xShare, [C_sign_share.rShares[1]], [B.yShares[1]]); + let C_sign = MPC.sign(signablePayload, C_sign_share.xShare, [A_sign_share.rShares[3]], [B.yShares[3]]); + signature = MPC.signCombine([A_sign, C_sign]); + rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]); + txBuilder = initTxBuilder(); + txBuilder.sender(sender, commonPub); + txBuilder.addSignature({ pub: nearKeyPair.getKeys().pub }, rawSignature); + signedTransaction = await txBuilder.build(); + signedTransaction.signature.length.should.equal(1); + signedTransaction.signature[0].should.equal(base58.encode(rawSignature)); + + // signing with B and C + B_sign_share = MPC.signShare(signablePayload, B_combine.pShare, [B_combine.jShares[3]]); + C_sign_share = MPC.signShare(signablePayload, C_combine.pShare, [C_combine.jShares[2]]); + B_sign = MPC.sign(signablePayload, B_sign_share.xShare, [C_sign_share.rShares[2]], [A.yShares[2]]); + C_sign = MPC.sign(signablePayload, C_sign_share.xShare, [B_sign_share.rShares[3]], [A.yShares[3]]); + signature = MPC.signCombine([B_sign, C_sign]); + rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]); + txBuilder = initTxBuilder(); + txBuilder.sender(sender, commonPub); + txBuilder.addSignature({ pub: nearKeyPair.getKeys().pub }, rawSignature); + signedTransaction = await txBuilder.build(); + signedTransaction.signature.length.should.equal(1); + signedTransaction.signature[0].should.equal(base58.encode(rawSignature)); + + const rebuiltTransaction = await factory.from(signedTransaction.toBroadcastFormat()).build(); + + rebuiltTransaction.signature[0].should.equal(base58.encode(rawSignature)); + }); + }); + }); +}); diff --git a/modules/sdk-coin-near/test/unit/transactionBuilder/transactionBuilder.ts b/modules/sdk-coin-near/test/unit/transactionBuilder/transactionBuilder.ts index 4344a4b195..8a68345d3c 100644 --- a/modules/sdk-coin-near/test/unit/transactionBuilder/transactionBuilder.ts +++ b/modules/sdk-coin-near/test/unit/transactionBuilder/transactionBuilder.ts @@ -17,7 +17,7 @@ describe('NEAR Transaction Builder', async () => { it('start and build an empty a transfer tx', async () => { const txBuilder = factory.getTransferBuilder(); txBuilder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); - txBuilder.nonce(1); + txBuilder.nonce(BigInt(1)); txBuilder.receiverId(testData.accounts.account2.address); txBuilder.recentBlockHash(testData.blockHash.block1); txBuilder.amount(testData.AMOUNT); @@ -31,7 +31,7 @@ describe('NEAR Transaction Builder', async () => { it('build and sign a transfer tx', async () => { const txBuilder = factory.getTransferBuilder(); txBuilder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); - txBuilder.nonce(1); + txBuilder.nonce(BigInt(1)); txBuilder.receiverId(testData.accounts.account2.address); txBuilder.recentBlockHash(testData.blockHash.block1); txBuilder.amount(testData.AMOUNT); diff --git a/modules/sdk-coin-near/test/unit/transactionBuilder/transferBuilder.ts b/modules/sdk-coin-near/test/unit/transactionBuilder/transferBuilder.ts index d48c391ad3..93b87b8fed 100644 --- a/modules/sdk-coin-near/test/unit/transactionBuilder/transferBuilder.ts +++ b/modules/sdk-coin-near/test/unit/transactionBuilder/transferBuilder.ts @@ -12,7 +12,7 @@ describe('Near Transfer Builder', () => { it('build a transfer tx unsigned', async () => { const txBuilder = factory.getTransferBuilder(); txBuilder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); - txBuilder.nonce(1); + txBuilder.nonce(BigInt(1)); txBuilder.receiverId(testData.accounts.account2.address); txBuilder.recentBlockHash(testData.blockHash.block1); txBuilder.amount(testData.AMOUNT); @@ -38,7 +38,7 @@ describe('Near Transfer Builder', () => { it('build a transfer tx signed', async () => { const txBuilder = factory.getTransferBuilder(); txBuilder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); - txBuilder.nonce(1); + txBuilder.nonce(BigInt(1)); txBuilder.receiverId(testData.accounts.account2.address); txBuilder.recentBlockHash(testData.blockHash.block1); txBuilder.amount(testData.AMOUNT); @@ -85,7 +85,7 @@ describe('Near Transfer Builder', () => { let txBuilder = factory.getTransferBuilder(); txBuilder.sender(testData.accounts.account1.address, testData.accounts.account1.publicKey); - txBuilder.nonce(1); + txBuilder.nonce(BigInt(1)); txBuilder.receiverId(testData.accounts.account2.address); txBuilder.recentBlockHash(testData.blockHash.block1); txBuilder.amount(testData.AMOUNT); @@ -102,7 +102,7 @@ describe('Near Transfer Builder', () => { let rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]); txBuilder = factory.getTransferBuilder(); txBuilder.sender(sender, commonPub); - txBuilder.nonce(1); + txBuilder.nonce(BigInt(1)); txBuilder.receiverId(testData.accounts.account2.address); txBuilder.recentBlockHash(testData.blockHash.block1); txBuilder.amount(testData.AMOUNT); @@ -120,7 +120,7 @@ describe('Near Transfer Builder', () => { rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]); txBuilder = factory.getTransferBuilder(); txBuilder.sender(sender, commonPub); - txBuilder.nonce(1); + txBuilder.nonce(BigInt(1)); txBuilder.receiverId(testData.accounts.account2.address); txBuilder.recentBlockHash(testData.blockHash.block1); txBuilder.amount(testData.AMOUNT); @@ -138,7 +138,7 @@ describe('Near Transfer Builder', () => { rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]); txBuilder = factory.getTransferBuilder(); txBuilder.sender(sender, commonPub); - txBuilder.nonce(1); + txBuilder.nonce(BigInt(1)); txBuilder.receiverId(testData.accounts.account2.address); txBuilder.recentBlockHash(testData.blockHash.block1); txBuilder.amount(testData.AMOUNT); diff --git a/modules/sdk-core/src/account-lib/baseCoin/enum.ts b/modules/sdk-core/src/account-lib/baseCoin/enum.ts index 0af1dea600..32b4ec68ec 100644 --- a/modules/sdk-core/src/account-lib/baseCoin/enum.ts +++ b/modules/sdk-core/src/account-lib/baseCoin/enum.ts @@ -78,6 +78,8 @@ export enum TransactionType { TrustLine, // Send Non Fungible Token (e.g. APT NFTs) SendNFT, + // register an account with ft (e.g. NEAR) + StorageDeposit, } /** diff --git a/yarn.lock b/yarn.lock index 1341b41581..593592c9be 100644 --- a/yarn.lock +++ b/yarn.lock @@ -816,6 +816,11 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.24.6": + version "7.27.3" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.3.tgz#10491113799fb8d77e1d9273384d5d68deeea8f6" + integrity sha512-7EYtGezsdiDMyY80+65EzwiGmcJqpmcZCojSXaRgdrBaGtWTgDZKq69cPIVped6MkIM78cTQ2GOiEYjwOlG4xw== + "@babel/template@^7.25.9", "@babel/template@^7.26.9", "@babel/template@^7.27.0": version "7.27.0" resolved "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz#b253e5406cc1df1c57dcd18f11760c2dbf40c0b4" @@ -1754,7 +1759,7 @@ resolved "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-5.0.0.tgz#dd81b32b2237bc32fb1b54534f8ff246a6c89d9b" integrity sha512-WuS1l7GJmB0n0HsXLozCoEFc9IwYgf3l0gCkKVYgR67puVF1O4OpEaN0hWmm1c+iHUHFCKt1hJrvy5toLg+6ag== -"@ethereumjs/rlp@^4.0.0-beta.2": +"@ethereumjs/rlp@^4.0.0-beta.2", "@ethereumjs/rlp@^4.0.1": version "4.0.1" resolved "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== @@ -1767,7 +1772,7 @@ "@ethereumjs/common" "^2.6.4" ethereumjs-util "^7.1.5" -"@ethereumjs/util@8.0.3", "@ethereumjs/util@^8.0.6": +"@ethereumjs/util@8.0.3": version "8.0.3" resolved "https://registry.npmjs.org/@ethereumjs/util/-/util-8.0.3.tgz#410c2dc8c6d519b29f1a471aa9b9df9952e41239" integrity sha512-0apCbwc8xAaie6W7q6QyogfyRS2BMU816a8KwpnpRw9Qrc6Bws+l7J3LfCLMt2iL6Wi8CYb0B29AeIr2N4vHnw== @@ -1776,6 +1781,15 @@ async "^3.2.4" ethereum-cryptography "^1.1.2" +"@ethereumjs/util@^8.0.6": + version "8.1.0" + resolved "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" + integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== + dependencies: + "@ethereumjs/rlp" "^4.0.1" + ethereum-cryptography "^2.0.0" + micro-ftch "^0.3.1" + "@ethersproject/abi@5.0.7": version "5.0.7" resolved "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz#79e52452bd3ca2956d0e1c964207a58ad1a0ee7b" @@ -3456,6 +3470,162 @@ dependencies: bs58 "^5.0.0" +"@near-js/accounts@1.4.1": + version "1.4.1" + resolved "https://registry.npmjs.org/@near-js/accounts/-/accounts-1.4.1.tgz#729692916862c21a2bcd36cb0c312b46540ac33c" + integrity sha512-ni3QT9H3NdrbVVKyx56yvz93r89Dvpc/vgVtiIK2OdXjkK6jcj+UKMDRQ6F7rd9qJOInLkHZbVBtcR6j1CXLjw== + dependencies: + "@near-js/crypto" "1.4.2" + "@near-js/providers" "1.0.3" + "@near-js/signers" "0.2.2" + "@near-js/transactions" "1.3.3" + "@near-js/types" "0.3.1" + "@near-js/utils" "1.1.0" + "@noble/hashes" "1.7.1" + borsh "1.0.0" + depd "2.0.0" + is-my-json-valid "^2.20.6" + lru_map "0.4.1" + near-abi "0.2.0" + +"@near-js/crypto@1.4.2": + version "1.4.2" + resolved "https://registry.npmjs.org/@near-js/crypto/-/crypto-1.4.2.tgz#b903b1de954a06d6e34457f78184c43086df1917" + integrity sha512-GRfchsyfWvSAPA1gI9hYhw5FH94Ac1BUo+Cmp5rSJt/V0K3xVzCWgOQxvv4R3kDnWjaXJEuAmpEEnr4Bp3FWrA== + dependencies: + "@near-js/types" "0.3.1" + "@near-js/utils" "1.1.0" + "@noble/curves" "1.8.1" + borsh "1.0.0" + randombytes "2.1.0" + secp256k1 "5.0.1" + +"@near-js/crypto@2.0.1", "@near-js/crypto@^2.0.1": + version "2.0.1" + resolved "https://registry.npmjs.org/@near-js/crypto/-/crypto-2.0.1.tgz#e148f5d1b7285b3189ec0464b2c6f9fa6dbc980f" + integrity sha512-UyH0by2a2XR4i1SctuwWprWpsLIL8uGX/XUbTxMAqOxbPWwvt/DGuG/eZFLoEQPyfuU5nLwkVuovrJXH/xSttA== + dependencies: + "@near-js/types" "2.0.1" + "@near-js/utils" "2.0.1" + "@noble/curves" "1.8.1" + borsh "1.0.0" + randombytes "2.1.0" + secp256k1 "5.0.1" + +"@near-js/keystores-browser@0.2.2": + version "0.2.2" + resolved "https://registry.npmjs.org/@near-js/keystores-browser/-/keystores-browser-0.2.2.tgz#9df046c9dcca91fc743d33e798ba4c205d5f673b" + integrity sha512-Pxqm7WGtUu6zj32vGCy9JcEDpZDSB5CCaLQDTQdF3GQyL0flyRv2I/guLAgU5FLoYxU7dJAX9mslJhPW7P2Bfw== + dependencies: + "@near-js/crypto" "1.4.2" + "@near-js/keystores" "0.2.2" + +"@near-js/keystores-node@0.1.2": + version "0.1.2" + resolved "https://registry.npmjs.org/@near-js/keystores-node/-/keystores-node-0.1.2.tgz#e8391cbda7de4123f293d51dfb55c060f537c5cd" + integrity sha512-MWLvTszZOVziiasqIT/LYNhUyWqOJjDGlsthOsY6dTL4ZcXjjmhmzrbFydIIeQr+CcEl5wukTo68ORI9JrHl6g== + dependencies: + "@near-js/crypto" "1.4.2" + "@near-js/keystores" "0.2.2" + +"@near-js/keystores@0.2.2": + version "0.2.2" + resolved "https://registry.npmjs.org/@near-js/keystores/-/keystores-0.2.2.tgz#c1ec215c39e8d279f226333364bc424b57842527" + integrity sha512-DLhi/3a4qJUY+wgphw2Jl4S+L0AKsUYm1mtU0WxKYV5OBwjOXvbGrXNfdkheYkfh3nHwrQgtjvtszX6LrRXLLw== + dependencies: + "@near-js/crypto" "1.4.2" + "@near-js/types" "0.3.1" + +"@near-js/providers@1.0.3": + version "1.0.3" + resolved "https://registry.npmjs.org/@near-js/providers/-/providers-1.0.3.tgz#918c5ffb8f9bb92f0d28198e9396a08c61b3754a" + integrity sha512-VJMboL14R/+MGKnlhhE3UPXCGYvMd1PpvF9OqZ9yBbulV7QVSIdTMfY4U1NnDfmUC2S3/rhAEr+3rMrIcNS7Fg== + dependencies: + "@near-js/transactions" "1.3.3" + "@near-js/types" "0.3.1" + "@near-js/utils" "1.1.0" + borsh "1.0.0" + exponential-backoff "^3.1.2" + optionalDependencies: + node-fetch "2.6.7" + +"@near-js/signers@0.2.2": + version "0.2.2" + resolved "https://registry.npmjs.org/@near-js/signers/-/signers-0.2.2.tgz#ae521e1ea72c9b49ad1dfc63f2d90d847207fea7" + integrity sha512-M6ib+af9zXAPRCjH2RyIS0+RhCmd9gxzCeIkQ+I2A3zjgGiEDkBZbYso9aKj8Zh2lPKKSH7h+u8JGymMOSwgyw== + dependencies: + "@near-js/crypto" "1.4.2" + "@near-js/keystores" "0.2.2" + "@noble/hashes" "1.3.3" + +"@near-js/transactions@1.3.3": + version "1.3.3" + resolved "https://registry.npmjs.org/@near-js/transactions/-/transactions-1.3.3.tgz#3b0c03861fc4b29322cedb03875cf80f52871dd2" + integrity sha512-1AXD+HuxlxYQmRTLQlkVmH+RAmV3HwkAT8dyZDu+I2fK/Ec9BQHXakOJUnOBws3ihF+akQhamIBS5T0EXX/Ylw== + dependencies: + "@near-js/crypto" "1.4.2" + "@near-js/signers" "0.2.2" + "@near-js/types" "0.3.1" + "@near-js/utils" "1.1.0" + "@noble/hashes" "1.7.1" + borsh "1.0.0" + +"@near-js/transactions@^2.0.1": + version "2.0.1" + resolved "https://registry.npmjs.org/@near-js/transactions/-/transactions-2.0.1.tgz#14aa4f456a04aee4209c59a09ca8ca5680955d47" + integrity sha512-dDS8U0WrtKzEUFiCMQlwS2MDouRIBujNzz+hsafJHMSJ5aT8aFpzHTaQqo17zKF6sOk+QbA+PQFp90G76aWF3A== + dependencies: + "@near-js/crypto" "2.0.1" + "@near-js/types" "2.0.1" + "@near-js/utils" "2.0.1" + "@noble/hashes" "1.7.1" + borsh "1.0.0" + +"@near-js/types@0.3.1": + version "0.3.1" + resolved "https://registry.npmjs.org/@near-js/types/-/types-0.3.1.tgz#35f2649f85881d72fc231a16142e1f0e3b0e8377" + integrity sha512-8qIA7ynAEAuVFNAQc0cqz2xRbfyJH3PaAG5J2MgPPhD18lu/tCGd6pzYg45hjhtiJJRFDRjh/FUWKS+ZiIIxUw== + +"@near-js/types@2.0.1": + version "2.0.1" + resolved "https://registry.npmjs.org/@near-js/types/-/types-2.0.1.tgz#cc17a0a2f6a7feed08cca6d92f71fffafbcb7a56" + integrity sha512-kXvAqp8oAc9vnhIlUCazfMx/eHhbyBPA0R0rwZ7ItbdV9tuQhI+lbf3C0EHcCG7NgopDLmf5MpbeIqgOcU3iMg== + +"@near-js/utils@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@near-js/utils/-/utils-1.1.0.tgz#fcdd0b7d9badb11d61f399755bead804b2a47d47" + integrity sha512-5XWRq7xpu8Wud9pRXe2U347KXyi0mXofedUY2DQ9TaqiZUcMIaN9xj7DbCs2v6dws3pJyYrT1KWxeNp5fSaY3w== + dependencies: + "@near-js/types" "0.3.1" + "@scure/base" "^1.2.0" + depd "2.0.0" + mustache "4.0.0" + +"@near-js/utils@2.0.1": + version "2.0.1" + resolved "https://registry.npmjs.org/@near-js/utils/-/utils-2.0.1.tgz#fcf4662abd320e4a0582de2f338ec7b73b810399" + integrity sha512-/i8DF5s/cEW77I2iA2SuTpvbG8j4F9ieiO8visCGp5wrjWepSlxWl0B2DxXRlNLkvTui5k8aK9VWTxGK6uni6Q== + dependencies: + "@near-js/types" "2.0.1" + "@scure/base" "^1.2.4" + depd "2.0.0" + mustache "4.0.0" + +"@near-js/wallet-account@1.3.3": + version "1.3.3" + resolved "https://registry.npmjs.org/@near-js/wallet-account/-/wallet-account-1.3.3.tgz#ac23509e0c1c124945a8539d3cd2f654aed727e8" + integrity sha512-GDzg/Kz0GBYF7tQfyQQQZ3vviwV8yD+8F2lYDzsWJiqIln7R1ov0zaXN4Tii86TeS21KPn2hHAsVu3Y4txa8OQ== + dependencies: + "@near-js/accounts" "1.4.1" + "@near-js/crypto" "1.4.2" + "@near-js/keystores" "0.2.2" + "@near-js/providers" "1.0.3" + "@near-js/signers" "0.2.2" + "@near-js/transactions" "1.3.3" + "@near-js/types" "0.3.1" + "@near-js/utils" "1.1.0" + borsh "1.0.0" + "@noble/curves@1.3.0", "@noble/curves@~1.3.0": version "1.3.0" resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e" @@ -4691,6 +4861,11 @@ resolved "https://registry.npmjs.org/@scure/base/-/base-1.2.4.tgz#002eb571a35d69bdb4c214d0995dff76a8dcd2a9" integrity sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ== +"@scure/base@^1.2.0", "@scure/base@^1.2.4": + version "1.2.5" + resolved "https://registry.npmjs.org/@scure/base/-/base-1.2.5.tgz#f9d1b232425b367d0dcb81c96611dcc651d58671" + integrity sha512-9rE6EOVeIQzt5TSu4v+K523F8u6DhBsoZWPGKlnCshhlDhy0kJzUX4V+tr2dWmzF1GdekvThABoEQBGBQI7xZw== + "@scure/base@~1.1.0", "@scure/base@~1.1.5", "@scure/base@~1.1.6": version "1.1.9" resolved "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1" @@ -4908,7 +5083,28 @@ "@solana/buffer-layout-utils" "^0.2.0" "@solana/web3.js" "^1.41.0" -"@solana/web3.js@1.92.1", "@solana/web3.js@1.95.8", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.41.0": +"@solana/web3.js@1.92.1": + version "1.92.1" + resolved "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.92.1.tgz#0c0fef31bbb20590ea5dfb63a578e5dfc4a111f1" + integrity sha512-72hytgOHfJLbvKT0+HRuFUhxxZpCnlo4zFDt37UHPel1DJbgqGOWo3xUf3VEPRWBvSRv0EH15g8MGatdj1PO9g== + dependencies: + "@babel/runtime" "^7.24.6" + "@noble/curves" "^1.4.0" + "@noble/hashes" "^1.4.0" + "@solana/buffer-layout" "^4.0.1" + agentkeepalive "^4.5.0" + bigint-buffer "^1.1.5" + bn.js "^5.2.1" + borsh "^0.7.0" + bs58 "^4.0.1" + buffer "6.0.3" + fast-stable-stringify "^1.0.0" + jayson "^4.1.0" + node-fetch "^2.7.0" + rpc-websockets "^7.11.1" + superstruct "^1.0.4" + +"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.41.0": version "1.95.8" resolved "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.95.8.tgz#2d49abda23f7a79a3cc499ab6680f7be11786ee1" integrity sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g== @@ -5496,7 +5692,7 @@ resolved "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.10.18.tgz#d442369fd2d06d5b2c607fae51c257b2f9caa94e" integrity sha512-jOk52a1Kz+1oU5fNWwAcNe64/GsE7r/Q6ronwDox0D3ETo/cr4ICMQyeXrj7G6FPW1n8YjRoAZA2F0XBr6GicQ== -"@types/json-schema@*", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.11", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -5513,7 +5709,7 @@ dependencies: "@types/node" "*" -"@types/keyv@3.1.4", "@types/keyv@^3.1.4": +"@types/keyv@^3.1.4": version "3.1.4" resolved "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== @@ -6927,7 +7123,45 @@ aws4@^1.8.0: resolved "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz#0aa167216965ac9474ccfa83892cfb6b3e1e52ef" integrity sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw== -axios@0.25.0, axios@0.27.2, axios@1.7.4, axios@^0.21.2, axios@^0.26.1, axios@^1.0.0, axios@^1.3.1, axios@^1.3.4, axios@^1.4.0, axios@^1.6.0, axios@^1.8.2: +axios@0.25.0: + version "0.25.0" + resolved "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz#349cfbb31331a9b4453190791760a8d35b093e0a" + integrity sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g== + dependencies: + follow-redirects "^1.14.7" + +axios@0.27.2: + version "0.27.2" + resolved "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== + dependencies: + follow-redirects "^1.14.9" + form-data "^4.0.0" + +axios@1.7.4: + version "1.7.4" + resolved "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2" + integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + +axios@^0.21.2: + version "0.21.4" + resolved "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + +axios@^0.26.1: + version "0.26.1" + resolved "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" + integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA== + dependencies: + follow-redirects "^1.14.8" + +axios@^1.0.0, axios@^1.3.1, axios@^1.3.4, axios@^1.4.0, axios@^1.6.0, axios@^1.8.2: version "1.8.4" resolved "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz#78990bb4bc63d2cae072952d374835950a82f447" integrity sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw== @@ -7050,7 +7284,7 @@ base64-arraybuffer@^1.0.2: resolved "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc" integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ== -base64-js@*, base64-js@^1.3.0, base64-js@^1.3.1: +base64-js@*, base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -7148,12 +7382,12 @@ bigint-mod-arith@^3.1.0: resolved "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.3.1.tgz#8ed33dc9f7886e552a7d47c239e051836e74cfa8" integrity sha512-pX/cYW3dCa87Jrzv6DAr8ivbbJRzEX5yGhdt8IutnX/PCIXfpx+mabWNK/M8qqh+zQ0J3thftUBHW0ByuUlG0w== -bignumber.js@4.1.0, bignumber.js@^4.0.0: +bignumber.js@^4.0.0: version "4.1.0" resolved "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz#db6f14067c140bd46624815a7916c92d9b6c24b1" integrity sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA== -bignumber.js@9.1.2, bignumber.js@^9.0.0, bignumber.js@^9.0.1, bignumber.js@^9.0.2, bignumber.js@^9.1.1, bignumber.js@^9.1.2: +bignumber.js@^9.0.0, bignumber.js@^9.0.1, bignumber.js@^9.0.2, bignumber.js@^9.1.1, bignumber.js@^9.1.2: version "9.1.2" resolved "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== @@ -7180,7 +7414,7 @@ binaryextensions@^4.16.0: resolved "https://registry.npmjs.org/binaryextensions/-/binaryextensions-4.19.0.tgz#7944b41ce6bbbcd3e544e05f65794ac48caaa132" integrity sha512-DRxnVbOi/1OgA5pA9EDiRT8gvVYeqfuN7TmPfLyt6cyho3KbHCi3EtDQf39TTmGDrR5dZ9CspdXhPkL/j/WGbg== -bindings@^1.3.0: +bindings@^1.3.0, bindings@^1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== @@ -7244,6 +7478,13 @@ bip39@^3.0.2: dependencies: "@noble/hashes" "^1.2.0" +bip66@^1.1.5: + version "1.1.5" + resolved "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + integrity sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw== + dependencies: + safe-buffer "^5.0.1" + bitcoin-ops@^1.3.0: version "1.4.1" resolved "https://registry.npmjs.org/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz#e45de620398e22fd4ca6023de43974ff42240278" @@ -7376,7 +7617,23 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^ resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz#215741fe3c9dba2d7e12c001d0cfdbae43975ba7" integrity sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg== -body-parser@1.19.2, body-parser@1.20.3, body-parser@^1.16.0, body-parser@^1.19.0, body-parser@^1.20.3: +body-parser@1.19.2: + version "1.19.2" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" + integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.7" + raw-body "2.4.3" + type-is "~1.6.18" + +body-parser@1.20.3, body-parser@^1.16.0, body-parser@^1.19.0, body-parser@^1.20.3: version "1.20.3" resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== @@ -7420,14 +7677,10 @@ borc@^2.1.1: json-text-sequence "~0.1.0" readable-stream "^3.6.0" -borsh@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/borsh/-/borsh-0.6.0.tgz#a7c9eeca6a31ca9e0607cb49f329cb659eb791e1" - integrity sha512-sl5k89ViqsThXQpYa9XDtz1sBl3l1lI313cFUY1HKr+wvMILnb+58xpkqTNrYbelh99dY7K8usxoCusQmqix9Q== - dependencies: - bn.js "^5.2.0" - bs58 "^4.0.0" - text-encoding-utf-8 "^1.0.2" +borsh@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/borsh/-/borsh-1.0.0.tgz#b564c8cc8f7a91e3772b9aef9e07f62b84213c1f" + integrity sha512-fSVWzzemnyfF89EPwlUNsrS5swF5CrtiN4e+h0/lLf4dz2he4L3ndM20PS9wj7ICSkXJe/TQUHdaPTq15b1mNQ== borsh@^0.7.0: version "0.7.0" @@ -7507,7 +7760,7 @@ browserify-aes@1.0.6: evp_bytestokey "^1.0.0" inherits "^2.0.1" -browserify-aes@^1.0.4, browserify-aes@^1.2.0: +browserify-aes@^1.0.4, browserify-aes@^1.0.6, browserify-aes@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== @@ -7701,7 +7954,16 @@ buffer-xor@^1.0.2, buffer-xor@^1.0.3: resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== -buffer@4.9.2, buffer@6.0.3, buffer@^5.0.2, buffer@^5.0.5, buffer@^5.1.0, buffer@^5.4.3, buffer@^5.5.0, buffer@^5.6.0, buffer@^5.7.1, buffer@^6.0.2, buffer@^6.0.3, buffer@~6.0.3: +buffer@4.9.2: + version "4.9.2" + resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffer@6.0.3, buffer@^6.0.2, buffer@^6.0.3, buffer@~6.0.3: version "6.0.3" resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== @@ -7709,6 +7971,14 @@ buffer@4.9.2, buffer@6.0.3, buffer@^5.0.2, buffer@^5.0.5, buffer@^5.1.0, buffer@ base64-js "^1.3.1" ieee754 "^1.2.1" +buffer@^5.0.2, buffer@^5.0.5, buffer@^5.1.0, buffer@^5.4.3, buffer@^5.5.0, buffer@^5.6.0, buffer@^5.7.1: + version "5.7.1" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + bufferutil@^4.0.1: version "4.0.9" resolved "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz#6e81739ad48a95cad45a279588e13e95e24a800a" @@ -7925,22 +8195,20 @@ caniuse-lite@^1.0.30001688, caniuse-lite@^1.0.30001702: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001710.tgz#2cda0c6071ddd43c01151c7f704a0e510a86612f" integrity sha512-B5C0I0UmaGqHgo5FuqJ7hBd4L57A4dDD+Xi+XX1nXOoxGeDdY4Ko38qJYOyqznBVJEqON5p8P1x5zRR3+rsnxA== -canvg@4.0.3, canvg@^3.0.11: - version "4.0.3" - resolved "https://registry.npmjs.org/canvg/-/canvg-4.0.3.tgz#1073a254ed9aed01a0ab53fb542c5bbecf7cf599" - integrity sha512-fKzMoMBwus3CWo1Uy8XJc4tqqn98RoRrGV6CsIkaNiQT5lOeHuMh4fOt+LXLzn2Wqtr4p/c2TOLz4xtu4oBlFA== +canvg@^3.0.11: + version "3.0.11" + resolved "https://registry.npmjs.org/canvg/-/canvg-3.0.11.tgz#4b4290a6c7fa36871fac2b14e432eff33b33cf2b" + integrity sha512-5ON+q7jCTgMp9cjpu4Jo6XbvfYwSB2Ow3kzHKfIyJfaCAOHLbdKPQqGKgfED/R5B+3TFFfe8pegYA+b423SRyA== dependencies: + "@babel/runtime" "^7.12.5" "@types/raf" "^3.4.0" + core-js "^3.8.3" raf "^3.4.1" + regenerator-runtime "^0.13.7" rgbcolor "^1.0.1" stackblur-canvas "^2.0.0" svg-pathdata "^6.0.3" -capability@^0.2.5: - version "0.2.5" - resolved "https://registry.npmjs.org/capability/-/capability-0.2.5.tgz#51ad87353f1936ffd77f2f21c74633a4dea88801" - integrity sha512-rsJZYVCgXd08sPqwmaIqjAd5SUTfonV0z/gDJ8D6cN8wQphky1kkAYEqQ+hmDxTw7UihvBfjUVUSY+DBEe44jg== - caseless@~0.12.0: version "0.12.0" resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -8754,6 +9022,11 @@ core-js@^3.6.0: resolved "https://registry.npmjs.org/core-js/-/core-js-3.41.0.tgz#57714dafb8c751a6095d028a7428f1fb5834a776" integrity sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA== +core-js@^3.8.3: + version "3.42.0" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.42.0.tgz#edbe91f78ac8cfb6df8d997e74d368a68082fe37" + integrity sha512-Sz4PP4ZA+Rq4II21qkNqOEDTDrCvcANId3xpIgB34NDkWc3UduWj2dqEtN9yZIq8Dk3HyPI33x9sqqU5C8sr0g== + core-util-is@1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -9370,7 +9643,7 @@ defined@^1.0.0, defined@~1.0.1: resolved "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== -degenerator@5.0.0, degenerator@^5.0.0: +degenerator@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/degenerator/-/degenerator-5.0.0.tgz#ccf1f07e95d81354398fbaf40c9d523202feb751" integrity sha512-pdRxyYVe0unlUE/eeXBxFdB8w8J7QNNf7hFE/BKOAlTCz0bkF9h1MC82ii0r1ypqB/PTKYDbg4K9SZT9yfd9Fg== @@ -9441,7 +9714,7 @@ depcheck@^1.4.3: semver "^7.5.4" yargs "^16.2.0" -depd@2.0.0, depd@^2.0.0, depd@~2.0.0: +depd@2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -9753,6 +10026,15 @@ dotignore@~0.1.2: dependencies: minimatch "^3.0.4" +drbg.js@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" + integrity sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g== + dependencies: + browserify-aes "^1.0.6" + create-hash "^1.1.2" + create-hmac "^1.1.4" + dts-bundle-generator@^9.3.1: version "9.5.1" resolved "https://registry.npmjs.org/dts-bundle-generator/-/dts-bundle-generator-9.5.1.tgz#7eac7f47a2d5b51bdaf581843e7f969b88bfc225" @@ -9854,7 +10136,20 @@ electron-to-chromium@^1.5.73: resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.132.tgz#081b8086d7cecc58732f7cc1f1c19306c5510c5f" integrity sha512-QgX9EBvWGmvSRa74zqfnG7+Eno0Ak0vftBll0Pt2/z5b3bEGYL6OUXLgKPtvx73dn3dvwrlyVkjPKRRlhLYTEg== -elliptic@6.5.4, elliptic@6.6.1, elliptic@^6.4.0, elliptic@^6.4.1, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4, elliptic@^6.5.5, elliptic@^6.5.7, elliptic@^6.6.1: +elliptic@6.5.4: + version "6.5.4" + resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +elliptic@6.6.1, elliptic@^6.4.0, elliptic@^6.4.1, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4, elliptic@^6.5.5, elliptic@^6.5.7: version "6.6.1" resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06" integrity sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g== @@ -10041,15 +10336,6 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -error-polyfill@^0.1.3: - version "0.1.3" - resolved "https://registry.npmjs.org/error-polyfill/-/error-polyfill-0.1.3.tgz#df848b61ad8834f7a5db69a70b9913df86721d15" - integrity sha512-XHJk60ufE+TG/ydwp4lilOog549iiQF2OAPhkk9DdiYWMrltz5yhDz/xnKuenNwP7gy3dsibssO5QpVhkrSzzg== - dependencies: - capability "^0.2.5" - o3 "^1.0.3" - u3 "^0.1.1" - es-abstract@^1.23.2, es-abstract@^1.23.5, es-abstract@^1.23.9: version "1.23.9" resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz#5b45994b7de78dada5c1bebf1379646b32b9d606" @@ -10544,6 +10830,13 @@ eth-lib@^0.1.26: ws "^3.0.0" xhr-request-promise "^0.1.2" +ethereum-bloom-filters@^1.0.6: + version "1.2.0" + resolved "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.2.0.tgz#8294f074c1a6cbd32c39d2cc77ce86ff14797dab" + integrity sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA== + dependencies: + "@noble/hashes" "^1.4.0" + ethereum-cryptography@^0.1.3: version "0.1.3" resolved "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" @@ -10764,7 +11057,7 @@ eventemitter3@^3.1.0: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== -eventemitter3@^4.0.0, eventemitter3@^4.0.4: +eventemitter3@^4.0.0, eventemitter3@^4.0.4, eventemitter3@^4.0.7: version "4.0.7" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== @@ -10779,10 +11072,10 @@ events@^3.2.0, events@^3.3.0: resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -eventsource@2.0.2, eventsource@^1.1.1: - version "2.0.2" - resolved "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz#76dfcc02930fb2ff339520b6d290da573a9e8508" - integrity sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA== +eventsource@^1.1.1: + version "1.1.2" + resolved "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz#bc75ae1c60209e7cb1541231980460343eaea7c2" + integrity sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" @@ -10866,7 +11159,7 @@ expo-random@^12.1.2: dependencies: base64-js "^1.3.0" -exponential-backoff@^3.1.1: +exponential-backoff@^3.1.1, exponential-backoff@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz#a8f26adb96bf78e8cd8ad1037928d5e5c0679d91" integrity sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA== @@ -11311,11 +11604,16 @@ flux@^4.0.1: fbemitter "^3.0.0" fbjs "^3.0.1" -follow-redirects@1.15.4, follow-redirects@^1.0.0, follow-redirects@^1.15.6: +follow-redirects@^1.0.0: version "1.15.4" resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== +follow-redirects@^1.14.0, follow-redirects@^1.14.7, follow-redirects@^1.14.8, follow-redirects@^1.14.9, follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + for-each@^0.3.3, for-each@^0.3.5, for-each@~0.3.3: version "0.3.5" resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47" @@ -11558,6 +11856,20 @@ gauge@^4.0.3: strip-ansi "^6.0.1" wide-align "^1.1.5" +generate-function@^2.0.0: + version "2.3.1" + resolved "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ== + dependencies: + is-property "^1.0.0" + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -12304,7 +12616,18 @@ http-deceiver@^1.2.7: resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== -http-errors@1.8.1, http-errors@^1.7.2: +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@1.8.1: version "1.8.1" resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== @@ -12507,7 +12830,7 @@ ieee754@1.1.13: resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== -ieee754@^1.1.13, ieee754@^1.2.1: +ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -12713,7 +13036,12 @@ io-ts-types@^0.5.16, io-ts-types@^0.5.19: resolved "https://registry.npmjs.org/io-ts-types/-/io-ts-types-0.5.19.tgz#9c04fa73f15992436605218a5686b610efa7a5d3" integrity sha512-kQOYYDZG5vKre+INIDZbLeDJe+oM+4zLpUkjXyTMyUfoCpjJNyi29ZLkuEAwcPufaYo3yu/BsemZtbdD+NtRfQ== -io-ts@2.0.1, "io-ts@npm:@bitgo-forks/io-ts@2.1.4": +io-ts@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/io-ts/-/io-ts-2.0.1.tgz#1261c12f915c2f48d16393a36966636b48a45aa1" + integrity sha512-RezD+WcCfW4VkMkEcQWL/Nmy/nqsWTvTYg7oUmTGzglvSSV2P9h2z1PVeREPFf0GWNzruYleAt1XCMQZSg1xxQ== + +"io-ts@npm:@bitgo-forks/io-ts@2.1.4": version "2.1.4" resolved "https://registry.npmjs.org/@bitgo-forks/io-ts/-/io-ts-2.1.4.tgz#a7431bb5473c5d5f9a94de8f8b058e189a298423" integrity sha512-jCt3WPfDM+wM0SJMGJkY0TS6JmaQ78ATAYtsppJYJfts8geOS/N/UftwAROXwv6azKAMz8uo163t6dWWwfsYug== @@ -12916,6 +13244,22 @@ is-map@^2.0.3: resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== +is-my-ip-valid@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz#f7220d1146257c98672e6fba097a9f3f2d348442" + integrity sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg== + +is-my-json-valid@^2.20.6: + version "2.20.6" + resolved "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz#a9d89e56a36493c77bda1440d69ae0dc46a08387" + integrity sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + is-my-ip-valid "^1.0.0" + jsonpointer "^5.0.0" + xtend "^4.0.0" + is-nan@^1.2.1, is-nan@^1.3.2: version "1.3.2" resolved "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" @@ -13003,6 +13347,11 @@ is-promise@^2.2.2: resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== +is-property@^1.0.0, is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== + is-regex@^1.1.4, is-regex@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" @@ -13125,22 +13474,32 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + isarray@2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" integrity sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ== +isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isarray@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== +isbinaryfile@^4.0.6: + version "4.0.10" + resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== -isbinaryfile@5.0.0, isbinaryfile@^4.0.6, isbinaryfile@^5.0.0: +isbinaryfile@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz#034b7e54989dab8986598cbcea41f66663c65234" integrity sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg== @@ -13285,6 +13644,24 @@ jasmine-core@^3.6.0: resolved "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.99.1.tgz#5bfa4b2d76618868bfac4c8ff08bb26fffa4120d" integrity sha512-Hu1dmuoGcZ7AfyynN3LsfruwMbxMALMka+YtZeGoLuDEySVmVAPaonkNoBRIw/ectu8b9tVQCJNgp4a4knp+tg== +jayson@^4.1.0: + version "4.2.0" + resolved "https://registry.npmjs.org/jayson/-/jayson-4.2.0.tgz#b71762393fa40bc9637eaf734ca6f40d3b8c0c93" + integrity sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg== + dependencies: + "@types/connect" "^3.4.33" + "@types/node" "^12.12.54" + "@types/ws" "^7.4.4" + commander "^2.20.3" + delay "^5.0.0" + es6-promisify "^5.0.0" + eyes "^0.1.8" + isomorphic-ws "^4.0.1" + json-stringify-safe "^5.0.1" + stream-json "^1.9.1" + uuid "^8.3.2" + ws "^7.5.10" + jayson@^4.1.1: version "4.1.3" resolved "https://registry.npmjs.org/jayson/-/jayson-4.1.3.tgz#db9be2e4287d9fef4fc05b5fe367abe792c2eee8" @@ -13520,7 +13897,14 @@ json-text-sequence@~0.1.0: dependencies: delimit-stream "0.1.0" -json5@^1.0.1, json5@^1.0.2, json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: +json5@^1.0.1, json5@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -13556,6 +13940,11 @@ jsonparse@^1.2.0, jsonparse@^1.3.1: resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== +jsonpointer@^5.0.0: + version "5.0.1" + resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" + integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== + jspdf@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/jspdf/-/jspdf-3.0.1.tgz#d81e1964f354f60412516eb2449ea2cccd4d2a3b" @@ -14258,6 +14647,11 @@ lru-queue@^0.1.0: dependencies: es5-ext "~0.10.2" +lru_map@0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/lru_map/-/lru_map-0.4.1.tgz#f7b4046283c79fb7370c36f8fca6aee4324b0a98" + integrity sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg== + lz-string@^1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" @@ -14514,6 +14908,11 @@ micro-eth-signer@0.7.2: "@scure/base" "~1.1.5" micro-packed "~0.5.1" +micro-ftch@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" + integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== + micro-packed@~0.5.1: version "0.5.3" resolved "https://registry.npmjs.org/micro-packed/-/micro-packed-0.5.3.tgz#b2bc45ccf10347b5f253d3a566f0c86fc0652445" @@ -14661,11 +15060,16 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@1.2.6, minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8, minimist@~1.2.0, minimist@~1.2.8: +minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6, minimist@~1.2.0: version "1.2.6" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== +minimist@^1.2.8, minimist@~1.2.8: + version "1.2.8" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + minipass-collect@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" @@ -14975,10 +15379,10 @@ multimatch@^5.0.0: arrify "^2.0.1" minimatch "^3.0.4" -mustache@^4.0.0: - version "4.2.0" - resolved "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" - integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== +mustache@4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/mustache/-/mustache-4.0.0.tgz#7f02465dbb5b435859d154831c032acdfbbefb31" + integrity sha512-FJgjyX/IVkbXBXYUwH+OYwQKqWpFPLaLVESd70yHjSDunwzV2hZOoTBvPf4KLoxesUzzyfTH6F784Uqd7Wm5yA== mute-stream@0.0.8, mute-stream@~0.0.4: version "0.0.8" @@ -14990,6 +15394,11 @@ nan@2.14.0: resolved "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== +nan@^2.14.0: + version "2.22.2" + resolved "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz#6b504fd029fb8f38c0990e52ad5c26772fdacfbb" + integrity sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ== + nano-json-stream-parser@^0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" @@ -15020,22 +15429,35 @@ natural-compare@^1.4.0: resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -near-api-js@^0.44.2: - version "0.44.2" - resolved "https://registry.npmjs.org/near-api-js/-/near-api-js-0.44.2.tgz#e451f68f2c56bd885c7b918db5818a3e6e9423d0" - integrity sha512-eMnc4V+geggapEUa3nU2p8HSHn/njtloI4P2mceHQWO8vDE1NGpnAw8FuTBrLmXSgIv9m6oocgFc9t3VNf5zwg== +near-abi@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/near-abi/-/near-abi-0.2.0.tgz#745b569d69d172f46cd2ecc06271974a6cd2fa48" + integrity sha512-kCwSf/3fraPU2zENK18sh+kKG4uKbEUEQdyWQkmW8ZofmLarObIz2+zAYjA1teDZLeMvEQew3UysnPDXgjneaA== dependencies: - bn.js "5.2.0" - borsh "^0.6.0" - bs58 "^4.0.0" - depd "^2.0.0" - error-polyfill "^0.1.3" - http-errors "^1.7.2" - js-sha256 "^0.9.0" - mustache "^4.0.0" - node-fetch "^2.6.1" - text-encoding-utf-8 "^1.0.2" - tweetnacl "^1.0.1" + "@types/json-schema" "^7.0.11" + +near-api-js@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/near-api-js/-/near-api-js-5.1.1.tgz#64905f74d0ad9ce0b4f5ad6ec4aaa8403b8e5968" + integrity sha512-h23BGSKxNv8ph+zU6snicstsVK1/CTXsQz4LuGGwoRE24Hj424nSe4+/1tzoiC285Ljf60kPAqRCmsfv9etF2g== + dependencies: + "@near-js/accounts" "1.4.1" + "@near-js/crypto" "1.4.2" + "@near-js/keystores" "0.2.2" + "@near-js/keystores-browser" "0.2.2" + "@near-js/keystores-node" "0.1.2" + "@near-js/providers" "1.0.3" + "@near-js/signers" "0.2.2" + "@near-js/transactions" "1.3.3" + "@near-js/types" "0.3.1" + "@near-js/utils" "1.1.0" + "@near-js/wallet-account" "1.3.3" + "@noble/curves" "1.8.1" + borsh "1.0.0" + depd "2.0.0" + http-errors "1.7.2" + near-abi "0.2.0" + node-fetch "2.6.7" negotiator@0.6.3: version "0.6.3" @@ -15542,13 +15964,6 @@ nyc@^15.0.0, nyc@^15.1.0: test-exclude "^6.0.0" yargs "^15.0.2" -o3@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/o3/-/o3-1.0.3.tgz#192ce877a882dfa6751f0412a865fafb2da1dac0" - integrity sha512-f+4n+vC6s4ysy7YO7O2gslWZBUu8Qj2i2OUJOvjRxQva7jVjYjB29jrr9NCjmxZQR0gzrOcv1RnqoYOeMs5VRQ== - dependencies: - capability "^0.2.5" - oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -16095,10 +16510,10 @@ parse-passwd@^1.0.0: resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== -parse-path@^5.0.0, parse-path@^7.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/parse-path/-/parse-path-5.0.0.tgz#f933152f3c6d34f4cf36cfc3d07b138ac113649d" - integrity sha512-qOpH55/+ZJ4jUu/oLO+ifUKjFPNZGfnPJtzvGzKN/4oLMil5m9OH4VpOj6++9/ytJcfks4kzH2hhi87GL/OU9A== +parse-path@^7.0.0: + version "7.1.0" + resolved "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz#41fb513cb122831807a4c7b29c8727947a09d8c6" + integrity sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw== dependencies: protocols "^2.0.0" @@ -16107,7 +16522,7 @@ parse-srcset@^1.0.2: resolved "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1" integrity sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q== -parse-url@8.1.0, parse-url@^8.1.0: +parse-url@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz#972e0827ed4b57fc85f0ea6b0d839f0d8a57a57d" integrity sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w== @@ -16195,15 +16610,27 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" -path-to-regexp@0.1.12, path-to-regexp@0.1.7: +path-to-regexp@0.1.12: version "0.1.12" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== -path-to-regexp@8.0.0, path-to-regexp@^1.7.0, path-to-regexp@^6.2.1: - version "8.0.0" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.0.0.tgz#92076ec6b2eaf08be7c3233484142c05e8866cf5" - integrity sha512-GAWaqWlTjYK/7SVpIUA6CTxmcg65SP30sbjdCvyYReosRkk7Z/LyHWwkK3Vu0FcIi0FNTADUs4eh1AsU5s10cg== +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-to-regexp@^1.7.0: + version "1.9.0" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz#5dc0753acbf8521ca2e0f137b4578b917b10cf24" + integrity sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g== + dependencies: + isarray "0.0.1" + +path-to-regexp@^6.2.1: + version "6.3.0" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz#2b6a26a337737a8e1416f9272ed0766b1c0389f4" + integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ== path-type@^3.0.0: version "3.0.0" @@ -17143,7 +17570,7 @@ randombytes@2.0.5: dependencies: safe-buffer "^5.1.0" -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: +randombytes@2.1.0, randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== @@ -17163,6 +17590,16 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== +raw-body@2.4.3: + version "2.4.3" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" + integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== + dependencies: + bytes "3.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + raw-body@2.5.2: version "2.5.2" resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" @@ -17477,7 +17914,7 @@ regenerate@^1.4.2: resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.2: +regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.7: version "0.13.11" resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== @@ -17816,6 +18253,18 @@ rlp@^2.0.0, rlp@^2.2.3, rlp@^2.2.4: dependencies: bn.js "^5.2.0" +rpc-websockets@^7.11.1: + version "7.11.2" + resolved "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.11.2.tgz#582910c425b9f2c860327481c1d1e0e431bf4a6d" + integrity sha512-pL9r5N6AVHlMN/vT98+fcO+5+/UcPLf/4tq+WUaid/PPUGS/ttJ3y8e9IqmaWKtShNAysMSjkczuEA49NuV7UQ== + dependencies: + eventemitter3 "^4.0.7" + uuid "^8.3.2" + ws "^8.5.0" + optionalDependencies: + bufferutil "^4.0.1" + utf-8-validate "^5.0.2" + rpc-websockets@^9.0.2: version "9.1.1" resolved "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.1.1.tgz#5764336f3623ee1c5cc8653b7335183e3c0c78bd" @@ -17984,7 +18433,21 @@ scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: resolved "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== -secp256k1@3.7.1, secp256k1@5.0.1, secp256k1@^3.0.1, secp256k1@^4.0.0, secp256k1@^4.0.1, secp256k1@^5.0.0: +secp256k1@3.7.1: + version "3.7.1" + resolved "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz#12e473e0e9a7c2f2d4d4818e722ad0e14cc1e2f1" + integrity sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g== + dependencies: + bindings "^1.5.0" + bip66 "^1.1.5" + bn.js "^4.11.8" + create-hash "^1.2.0" + drbg.js "^1.0.1" + elliptic "^6.4.1" + nan "^2.14.0" + safe-buffer "^5.1.2" + +secp256k1@5.0.1, secp256k1@^5.0.0: version "5.0.1" resolved "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.1.tgz#dc2c86187d48ff2da756f0f7e96417ee03c414b1" integrity sha512-lDFs9AAIaWP9UCdtWrotXWWF9t8PWgQDcxqgAnpM9rMqxb3Oaq2J0thzPVSxBwdJgyQtkU/sYtFtbM1RSt/iYA== @@ -17993,6 +18456,29 @@ secp256k1@3.7.1, secp256k1@5.0.1, secp256k1@^3.0.1, secp256k1@^4.0.0, secp256k1@ node-addon-api "^5.0.0" node-gyp-build "^4.2.0" +secp256k1@^3.0.1: + version "3.8.1" + resolved "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.1.tgz#b62a62a882d6b16f9b51fe599c6b3a861e36c59f" + integrity sha512-tArjQw2P0RTdY7QmkNehgp6TVvQXq6ulIhxv8gaH6YubKG/wxxAoNKcbuXjDhybbc+b2Ihc7e0xxiGN744UIiQ== + dependencies: + bindings "^1.5.0" + bip66 "^1.1.5" + bn.js "^4.11.8" + create-hash "^1.2.0" + drbg.js "^1.0.1" + elliptic "^6.5.7" + nan "^2.14.0" + safe-buffer "^5.1.2" + +secp256k1@^4.0.0, secp256k1@^4.0.1: + version "4.0.4" + resolved "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.4.tgz#58f0bfe1830fe777d9ca1ffc7574962a8189f8ab" + integrity sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw== + dependencies: + elliptic "^6.5.7" + node-addon-api "^5.0.0" + node-gyp-build "^4.2.0" + secrets.js-grempe@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/secrets.js-grempe/-/secrets.js-grempe-1.1.0.tgz#bb3b606dd68637ca244681a10fdee6c512049294" @@ -18192,6 +18678,11 @@ setprototypeof@1.1.0: resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -18569,7 +19060,7 @@ socks-proxy-agent@^8.0.2, socks-proxy-agent@^8.0.5: debug "^4.3.4" socks "^2.8.3" -socks@2.7.3, socks@^2.6.2, socks@^2.8.3: +socks@^2.6.2: version "2.7.3" resolved "https://registry.npmjs.org/socks/-/socks-2.7.3.tgz#7d8a75d7ce845c0a96f710917174dba0d543a785" integrity sha512-vfuYK48HXCTFD03G/1/zkIls3Ebr2YNa4qU9gHDZdblHLiqhJrJGkY3+0Nx0JpN9qBhJbVObc1CNciT1bIZJxw== @@ -18577,6 +19068,14 @@ socks@2.7.3, socks@^2.6.2, socks@^2.8.3: ip-address "^9.0.5" smart-buffer "^4.2.0" +socks@^2.8.3: + version "2.8.4" + resolved "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz#07109755cdd4da03269bda4725baa061ab56d5cc" + integrity sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ== + dependencies: + ip-address "^9.0.5" + smart-buffer "^4.2.0" + sodium-native@^3.3.0: version "3.4.1" resolved "https://registry.npmjs.org/sodium-native/-/sodium-native-3.4.1.tgz#44616c07ccecea15195f553af88b3e574b659741" @@ -18615,7 +19114,7 @@ source-list-map@^2.0.0: resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== -source-map-support@~0.5.20: +source-map-support@~0.5.12, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -18847,6 +19346,11 @@ stream-browserify@^2.0.0: inherits "~2.0.1" readable-stream "^2.0.2" +stream-chain@^2.2.5: + version "2.2.5" + resolved "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz#b30967e8f14ee033c5b9a19bbe8a2cba90ba0d09" + integrity sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA== + stream-combiner2@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" @@ -18876,6 +19380,13 @@ stream-http@^3.1.0, stream-http@^3.2.0: readable-stream "^3.6.0" xtend "^4.0.2" +stream-json@^1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz#e3fec03e984a503718946c170db7d74556c2a187" + integrity sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw== + dependencies: + stream-chain "^2.2.5" + stream-splicer@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz#0b13b7ee2b5ac7e0609a7463d83899589a363fcd" @@ -19142,7 +19653,7 @@ superagent@^9.0.1: mime "2.6.0" qs "^6.11.0" -superstruct@^1.0.3: +superstruct@^1.0.3, superstruct@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/superstruct/-/superstruct-1.0.4.tgz#0adb99a7578bd2f1c526220da6571b2d485d91ca" integrity sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ== @@ -19333,7 +19844,16 @@ terser-webpack-plugin@^5.3.11, terser-webpack-plugin@^5.3.3: serialize-javascript "^6.0.2" terser "^5.31.1" -terser@^4.6.3, terser@^5.10.0, terser@^5.14.2, terser@^5.31.1: +terser@^4.6.3: + version "4.8.1" + resolved "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" + integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +terser@^5.10.0, terser@^5.14.2, terser@^5.31.1: version "5.39.0" resolved "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz#0e82033ed57b3ddf1f96708d123cca717d86ca3a" integrity sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw== @@ -19506,6 +20026,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + toidentifier@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" @@ -19681,7 +20206,7 @@ tweetnacl-util@^0.15.0, tweetnacl-util@^0.15.1: resolved "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== -tweetnacl@1.0.3, tweetnacl@^1.0.0, tweetnacl@^1.0.1, tweetnacl@^1.0.3: +tweetnacl@1.0.3, tweetnacl@^1.0.0, tweetnacl@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== @@ -19856,15 +20381,15 @@ typescript@>=5.0.2: resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== -u3@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/u3/-/u3-0.1.1.tgz#5f52044f42ee76cd8de33148829e14528494b73b" - integrity sha512-+J5D5ir763y+Am/QY6hXNRlwljIeRMZMGs0cT6qqZVVzzT3X3nFPXVyPOFRMOR4kupB0T8JnCdpWdp6Q/iXn3w== +ua-parser-js@0.7.22: + version "0.7.22" + resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.22.tgz#960df60a5f911ea8f1c818f3747b99c6e177eae3" + integrity sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q== -ua-parser-js@0.7.22, "ua-parser-js@>0.7.30 <0.8.0", ua-parser-js@^1.0.35: - version "0.7.40" - resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz#c87d83b7bb25822ecfa6397a0da5903934ea1562" - integrity sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ== +ua-parser-js@^1.0.35: + version "1.0.40" + resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.40.tgz#ac6aff4fd8ea3e794a6aa743ec9c2fc29e75b675" + integrity sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew== uc.micro@^2.0.0, uc.micro@^2.1.0: version "2.1.0" @@ -20387,13 +20912,6 @@ web3-core@1.3.6: web3-core-requestmanager "1.3.6" web3-utils "1.3.6" -web3-errors@^1.1.4, web3-errors@^1.2.0: - version "1.3.1" - resolved "https://registry.npmjs.org/web3-errors/-/web3-errors-1.3.1.tgz#163bc4d869f98614760b683d733c3ed1fb415d98" - integrity sha512-w3NMJujH+ZSW4ltIZZKtdbkbyQEvBzyp3JRn59Ckli0Nz4VMsVq8aF1bLWM7A2kuQ+yVEm3ySeNU+7mSRwx7RQ== - dependencies: - web3-types "^1.10.0" - web3-eth-abi@1.3.6: version "1.3.6" resolved "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.3.6.tgz#4272ca48d817aa651bbf97b269f5ff10abc2b8a9" @@ -20535,32 +21053,19 @@ web3-shh@1.3.6: web3-core-subscriptions "1.3.6" web3-net "1.3.6" -web3-types@^1.10.0, web3-types@^1.5.0, web3-types@^1.6.0: - version "1.10.0" - resolved "https://registry.npmjs.org/web3-types/-/web3-types-1.10.0.tgz#41b0b4d2dd75e919d5b6f37bf139e29f445db04e" - integrity sha512-0IXoaAFtFc8Yin7cCdQfB9ZmjafrbP6BO0f0KT/khMhXKUpoJ6yShrVhiNpyRBo8QQjuOagsWzwSK2H49I7sbw== - -web3-utils@1.3.6, web3-utils@4.2.1: - version "4.2.1" - resolved "https://registry.npmjs.org/web3-utils/-/web3-utils-4.2.1.tgz#326bc6e9e4d047f7b38ba68bee1399c4f9f621e3" - integrity sha512-Fk29BlEqD9Q9Cnw4pBkKw7czcXiRpsSco/BzEUl4ye0ZTSHANQFfjsfQmNm4t7uY11u6Ah+8F3tNjBeU4CA80A== - dependencies: - ethereum-cryptography "^2.0.0" - eventemitter3 "^5.0.1" - web3-errors "^1.1.4" - web3-types "^1.5.0" - web3-validator "^2.0.4" - -web3-validator@^2.0.4: - version "2.0.6" - resolved "https://registry.npmjs.org/web3-validator/-/web3-validator-2.0.6.tgz#a0cdaa39e1d1708ece5fae155b034e29d6a19248" - integrity sha512-qn9id0/l1bWmvH4XfnG/JtGKKwut2Vokl6YXP5Kfg424npysmtRLe9DgiNBM9Op7QL/aSiaA0TVXibuIuWcizg== +web3-utils@1.3.6: + version "1.3.6" + resolved "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz#390bc9fa3a7179746963cfaca55bb80ac4d8dc10" + integrity sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg== dependencies: - ethereum-cryptography "^2.0.0" - util "^0.12.5" - web3-errors "^1.2.0" - web3-types "^1.6.0" - zod "^3.21.4" + bn.js "^4.11.9" + eth-lib "0.2.8" + ethereum-bloom-filters "^1.0.6" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + underscore "1.12.1" + utf8 "3.0.0" web3@1.3.6: version "1.3.6" @@ -21256,8 +21761,3 @@ yocto-queue@^1.0.0: version "1.2.1" resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz#36d7c4739f775b3cbc28e6136e21aa057adec418" integrity sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg== - -zod@^3.21.4: - version "3.24.2" - resolved "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz#8efa74126287c675e92f46871cfc8d15c34372b3" - integrity sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==