npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@brinkninja/sdk

v5.0.0-beta.61

Published

This module can be used to interact with Brink proxy accounts, either as the account owner/signer or as an executor of messages signed by the account owner/signer.

Downloads

195

Readme

Brink SDK

This module can be used to interact with Brink proxy accounts, either as the account owner/signer or as an executor of messages signed by the account owner/signer.

Installation

npm install @brinkninja/sdk

Strategies

Creating Strategies

Strategies can be built from lower-level primitives:

  const { Strategy, Order, UniV3TWAP, useBit, marketSwapExactInput } = brink

  // configure a TWAP USDC-ETH oracle
  const oracle_USDC_ETH = UniV3TWAP({
    baseToken: USDC_address,
    quoteToken: WETH_address,
    time: 1000,
    feePool: 500
  })

  // price ~1000 ETH/USDC
  const p = 0.001;

  // construct a "stop-loss" strategy
  const strategy = Strategy.create(
    Order.create(
      useBit({                    // replay bit
        bitmapIndex: 0,
        bit: 1
      }),
      requireBlockNotMined({      // expiry
        blockNumber: 16802111
      }),
      requireUint256LowerBound({  // price oracle check
        oracle: oracle_USDC_ETH,
        price: p
      }),
      marketSwapExactInput({      // market swap
        oracle: oracle_USDC_ETH,
        owner: ownerAddress,
        tokenIn: USDC_address,
        tokenOut: WETH_address,
        tokenInAmount: 3000_000000, // 3k USDC
        feePercent: 1_0000, // 1% fee
        feeMin: 0
      })
    )
  )

Higher level types are provided for specific recipes

  const { StopLoss, Oracles } = brink

  const stopLoss = StopLoss.create({
    bitmapIndex: 0,
    bit: 1,
    expiryBlock: 16802111,
    oracle: oracle_USDC_ETH,
    price: p,
    owner: ownerAddress,
    tokenIn: USDC_address,
    tokenOut: WETH_address,
    tokenInAmount: 3000_000000, // 3k USDC
    feePercent: 1_0000, // 1% fee
    feeMin: 0
  })

Strategy Objects

Oracles

  UniV3TWAP({
    baseToken,
    quoteToken,
    time,
    feePool
  })

  ReservoirFloorPrice({
    priceKind,
    twapSeconds,
    contractAddress,
    timestamp
  })

Oracles implement an IOracle interface

  IOracle {
    contractAddress(); // returns the oracle contract address
    params();          // returns bytes for oracle primitive params calls
    value();           // reads and returns the value of the oracle on-chain
  }

Strategy

  Strategy {
    create(Order1, ... OrderN); // builds and returns a StrategyInstance
  }

  StrategyInstance {
    orders();         // returns orders
    beforeCalls();
    afterCalls();
    bytes();     // returns encoded strategy bytes for signing
  }

Order

Base order type

  Order {
    create(Primitive1, ... PrimitiveN); // builds and returns an OrderInstance
  }

  OrderInstance {
    primitives();   // returns primitives
    bytes();        // returns encoded bytes for the order
  }

We can also support more specific order types for convenience

  LimitSwap {}
  MarketSwap {}
  StopLossMarketSwap {}
  StopLossLimitSwap {}
  ...

Primitives

These are mapped from Primitives01.sol

  requireBitNotUsed()
  requireBitUsed()
  useBit()
  requireBlockMined()
  requireBlockNotMined()
  requireUint256LowerBound()
  requireUint256UpperBound()
  transfer()
  marketSwapExactInput()
  marketSwapExactOutput()
  limitSwap()
  ...

All return a base primitive instance

  PrimitiveInstance {
    params(); // returns params
    bytes();  // returns encoded bytes for the primitive calldata
  }

Recipes

Recipes implement IRecipe interface

  IRecipe {
    create(<params>);             // create the recipe
    params();                     // return the recipe's params
    strategy<StrategyInstance>;   // the wrapped strategy
  }

Recipe types

  StopLoss {
    params: {
      bitmapIndex,
      bit,
      expiryBlock,
      oracle,
      price,
      owner,
      tokenIn,
      tokenOut,
      tokenInAmount,
      feePercent,
      feeMin
    }
  }

  Bracket {
    params: {
      bitmapIndex,
      bit,
      expiryBlock,
      oracle,
      stopLossPrice,
      takeProfitPrice,
      owner,
      tokenIn,
      tokenOut,
      tokenInAmount,
      feePercent,
      feeMin
    }
  }

  ...

Account

Setup


Create an account instance with the address of the account owner, and an ethers.js provider and signer. The ethers.js provider and signer will be used for sending transactions to the account.

const brink = require('@brinkninja/sdk')
const { Account } = brink({ provider, signer })
const account = Account(ownerAddress)

Read-only Methods

These methods are available to read from account contract state

isDeployed()

Returns true if the account has been deployed

const deployed = await account.isDeployed()

bitUsed(bitmapIndex, bit)

Returns true if the given bitmapIndex and bit have been used for a previous limit swap or cancel transaction

Transaction Methods

These methods issue transactions to an account contract. They wrap ethers.js Contract Meta-class methods and can be used in the same way.

The Account instance exposes the ethers.js write method analysis properties estimateGas, populateTransaction, and callStatic. These can be used for any Account transaction. For example, getting transaction data without submitting the transaction can be done like this:

const txData = await account.populateTransaction.ApprovalSwapsV1.tokenToToken(swapSignedMsg, recipientAddress, toAddress, callData)

All of these transactions (except for deploy()) will include the desired action after account deployment, if the account has not been deployed yet, using DeployAndExecute.sol. If the account is already deployed, the action will be executed directly on the account contract.

deploy()

Deploys the account contract. Throws an error if the contract is already deployed

Example:

const tx = await account.deploy()

externalCall(value, to, data)

Calls externalCall on the account contract.

This can only be called if the ethers.js signer is the owner of the account

Example:

const tx = await account.externalCall(value, to, data)

delegateCall(to, data)

Calls delegateCall on the account contract.

This can only be called if the ethers.js signer is the owner of the account

Example:

const tx = await account.delegateCall(to, data)

metaDelegateCall(signedMessage, unsignedDataArray)

Calls metaDelegateCall on the account contract.

This can only be called with a valid message signed by the owner of the account

Example:

const tx = await account.metaDelegateCall(signedMessage, [unsignedTo, unsignedData])

Verifier metaDelegateCall methods

All contract methods in https://github.com/brinktrade/brink-verifiers/tree/177ee40291d92f3b0da371ea1939e11964b0de18/contracts/Verifiers contracts can be executed through metaDelegateCall using the SDK.

For example, a ApprovalSwapsV1.tokenToToken() verifier signed message can be executed by calling account.ApprovalSwapsV1.tokenToToken():

  await account.ApprovalSwapsV1.tokenToToken(ethToTokenSignedMessage, unsignedRecipient, unsignedTo, unsignedData)

Each verifier function takes a signed message object from AccountSigner as the first param, followed by any unsigned params required by the verifier function.

Supported functions are:

  account.CancelVerifier.cancel()
  account.TransferVerifier.tokenTransfer()
  account.TransferVerifier.ethTransfer()
  account.NftTransferVerifier.nftTransfer()
  account.ApprovalSwapsV1.tokenToToken()
  account.ApprovalSwapsV1.tokenToNft()
  account.ApprovalSwapsV1.nftToToken()
  account.ApprovalSwapsV1.tokenToERC1155()
  account.ApprovalSwapsV1.ERC1155ToToken()
  account.ApprovalSwapsV1.ERC1155ToERC1155()

AccountSigner

Handles signing of account messages. These authorize actions that can be taken on the account by executors.

Messages are returned in this format:

{
  message: '<signed message hash>',
  EIP712TypedData: <object with decoded EIP712 typed data>,
  signature: '<the signature>',
  signer: '<address of the signer>',
  accountAddress: '<address of the account>',
  functionName: '<function on Account.sol that is authorized by this message>',
  signedParams: <array of signed parameters>
}

Setup

Create an instance of accountSigner with an ethers.js signer and network. The ethers.js signer will be used for all account message signing

const brink = require('@brinkninja/sdk')
const { AccountSigner } = brink({ network })
const accountSigner = AccountSigner(signer, { network })

accountAddress()

Returns the address of the account. This is computed based on the signer's address. Every signer address has a unique account address, which is known before account deployment. Account address is the same on all EVM chains for a given signer.

signerAddress()

Returns the address of the signer

verifier signing functions

Supported functions are:

  accountSigner.CancelVerifier.signCancel()
  accountSigner.TransferVerifier.signTokenTransfer()
  accountSigner.TransferVerifier.signEthTransfer()
  accountSigner.NftTransferVerifier.signNftTransfer()
  accountSigner.ApprovalSwapsV1.signTokenToToken()
  accountSigner.ApprovalSwapsV1.signTokenToNft()
  accountSigner.ApprovalSwapsV1.signNftToToken()
  accountSigner.ApprovalSwapsV1.signTokenToERC1155()
  accountSigner.ApprovalSwapsV1.signERC1155ToToken()
  accountSigner.ApprovalSwapsV1.signERC1155ToERC1155()

Supported Verifier Contracts

| Contract | Address | Networks | | --- | --- | --- | | ApprovalSwapsV1.sol | 0x6ef84B098A812B8f4C81cD6d0B0A5a64d17C9B3e |mainnet, goerli| | CancelVerifier.sol | 0xE0670a90E67eda0126D54843267b27Ca6343B2d8 |mainnet, goerli| | TransferVerifier.sol | 0x6df5AE08Ec7aE5CC2E9e3b0850A61AD7C73bC9A9 |mainnet, goerli| | NftTransferVerifier.sol | 0x946CBd55EA50619C599d69Ab230Dff8707987D00 |mainnet, goerli|

Verifier Repos

https://github.com/brinktrade/brink-verifiers https://github.com/brinktrade/brink-verifiers-v2

Custom Verifier Setup

*** WARNING: SIGNING MESSAGES WITH UNSECURE VERIFIER CONTRACTS COULD PUT YOUR FUNDS AT RISK ***

To use custom verifiers, provide an array of verifier definitions:

  const { AccountSigner } = brink({
    network: 'hardhat',
    verifiers: [{
      "functionName": "myFunction",
      "functionSignature": "myFunction(uint256,uint256)",
      "functionSignatureHash": "0x3c447f23",
      "contractName": "MyVerifier",
      "contractAddress": "0xE100eF1C4339Dd4E4b54d5cBB6CcEfA96071E227",
      "paramTypes": [
        {
          "name": "paramOne",
          "type": "uint256",
          "signed": true
        },
        {
          "name": "paramTwo",
          "type": "uint256",
          "signed": false
        }
      ]
    }]
  })
  const signerWithCustomVerifiers = AccountSigner(ethersSigner)