Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@collabland/chain

Package Overview
Dependencies
Maintainers
1
Versions
69
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@collabland/chain - npm Package Compare versions

Comparing version 0.2.6 to 0.3.0

31

dist/base-chain-connector.d.ts
import { Amount, AssetRequest, AssetResponse, Chain, ChainConnector, ChainType, NativeCurrency, TokenAsset, TokenContract, TokenId, TokenMetadata } from './types';
/**
* Base chain connector
*
* @typeParam AMT - Amount type
* @typeParam TID - Token id type
* @typeParam M - Token metadata type
*/
export declare abstract class BaseChainConnector<AMT = Amount, TID = TokenId, M = TokenMetadata> implements ChainConnector<AMT, TID, M> {
abstract chainType: ChainType;
/**
* Native currency of the chain
*/
abstract nativeCurrency: NativeCurrency;
/**
* Check if the token spec is for NFT
* @param tokenSpec - Token spec
*/
abstract isNFT(tokenSpec: string): boolean;
/**
* Check if the token spec is for FT
* @param tokenSpec - Token spec
*/
abstract isFT(tokenSpec: string): boolean;
abstract getAmount(val: number | string): AMT;
/**
* Convert the value to `AMT`
* @param val - Value
*/
abstract toAmount(val: number | string | AMT): AMT;
/**
* Convert the token id to `TID`
* @param id
*/
abstract toTokenId(id: number | string | TID): TID;
protected concurrency: number;

@@ -12,5 +39,5 @@ getBalance(chain: Chain, account: string): Promise<AMT>;

getNFTBalance(chain: Chain, account: string, nftContract: TokenContract, tokenType?: TID): Promise<TokenAsset<TID, M, AMT>[]>;
getBalances(chain: Chain, account: string, ...requests: AssetRequest<TID>[]): Promise<AssetResponse<AMT, TID, M>[]>;
getBalances(chain: Chain, account: string, ...requests: AssetRequest<TID | string | number>[]): Promise<AssetResponse<AMT, TID, M>[]>;
getAssetTypes(chain: Chain, account: string): Promise<AssetRequest<TID>[]>;
getAssets(chain: Chain, account: string): Promise<AssetResponse<AMT, TID, M>[]>;
}

@@ -10,2 +10,9 @@ "use strict";

const types_1 = require("./types");
/**
* Base chain connector
*
* @typeParam AMT - Amount type
* @typeParam TID - Token id type
* @typeParam M - Token metadata type
*/
class BaseChainConnector {

@@ -25,3 +32,8 @@ constructor() {

async getBalances(chain, account, ...requests) {
const assets = common_1.pMap(requests, async (req) => {
const assetRequests = requests.map(r => ({
address: r.address,
tokenSpec: r.tokenSpec,
tokenType: r.tokenType != null ? this.toTokenId(r.tokenType) : undefined,
}));
const assets = common_1.pMap(assetRequests, async (req) => {
let asset;

@@ -42,3 +54,3 @@ if (req.address === '' ||

const nfts = await this.getNFTBalance(chain, account, req, req.tokenType);
asset = { balance: this.getAmount(nfts.length), tokens: nfts, ...req };
asset = { balance: this.toAmount(nfts.length), tokens: nfts, ...req };
return asset;

@@ -45,0 +57,0 @@ }

@@ -15,9 +15,69 @@ /**

export interface Chain {
type: ChainType;
/**
* Block chain type
*/
type: ChainType | string;
/**
* Chain id
*/
chainId?: string;
/**
* Chain network
*/
network: string;
/**
* RPC URL
*/
rpcUrl?: string;
/**
* Indexer URL
*/
indexerUrl?: string;
}
/**
* A blockchain resource
*/
export interface ChainResource extends Chain {
/**
* Extra parameters
*/
params?: Record<string, string>;
/**
* The resource path
*/
path?: string;
/**
* Account address or name
*/
account?: string;
/**
* Token contract
*/
contract?: TokenContract;
/**
* Token id
*/
tokenId?: string;
}
/**
* Get the uri for a given chain resource in the form of
* - `evm:mainnet/<account>`
* - `evm:mainnet/erc20/<erc20-contract-address>`
* - `evm:mainnet/erc721/<erc721-contract-address>/<token-id>`
*
* Inspired by https://github.com/ChainAgnostic/CAIPs
*
* @param chainResource - Chain resource
* @returns
*/
export declare function getChainUri(chainResource: ChainResource): string;
/**
* Parse the chain resource URI into an object
* - `evm:mainnet?rpcUrl=...`
* - `evm:1`
* - `near:testnet`
* @param uri - Chain resource uri
*/
export declare function parseChainUri(uri: string): ChainResource;
/**
* Default type for amount

@@ -142,3 +202,3 @@ */

*/
getBalances(chain: Chain, account: string, ...requests: AssetRequest<TID>[]): Promise<AssetResponse<AMT, TID, M>[]>;
getBalances(chain: Chain, account: string, ...requests: AssetRequest<TID | string | number>[]): Promise<AssetResponse<AMT, TID, M>[]>;
/**

@@ -145,0 +205,0 @@ * Get balances for the given account on the chain

@@ -7,3 +7,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.NATIVE_TOKEN = exports.ChainType = void 0;
exports.NATIVE_TOKEN = exports.parseChainUri = exports.getChainUri = exports.ChainType = void 0;
const common_1 = require("@collabland/common");
const debug = common_1.debugFactory('collabland:chain');
/**

@@ -20,2 +22,102 @@ * Chain type

})(ChainType = exports.ChainType || (exports.ChainType = {}));
/**
* Get the uri for a given chain resource in the form of
* - `evm:mainnet/<account>`
* - `evm:mainnet/erc20/<erc20-contract-address>`
* - `evm:mainnet/erc721/<erc721-contract-address>/<token-id>`
*
* Inspired by https://github.com/ChainAgnostic/CAIPs
*
* @param chainResource - Chain resource
* @returns
*/
function getChainUri(chainResource) {
var _a, _b, _c, _d, _e;
const protocol = chainResource.type;
const path = [
(_a = chainResource.chainId) !== null && _a !== void 0 ? _a : chainResource.network,
(_c = (_b = chainResource.path) !== null && _b !== void 0 ? _b : chainResource.account) !== null && _c !== void 0 ? _c : (chainResource.contract
? `${chainResource.contract.tokenSpec.toLowerCase()}:${chainResource.contract.address}`
: ''),
(_d = chainResource.tokenId) !== null && _d !== void 0 ? _d : '',
]
.filter(p => !!p)
.join('/');
const params = (_e = chainResource.params) !== null && _e !== void 0 ? _e : {};
if (chainResource.rpcUrl) {
params.rpcUrl = chainResource.rpcUrl;
}
if (chainResource.indexerUrl) {
params.indexerUrl = chainResource.indexerUrl;
}
let query = Object.entries(params)
.map(p => `${p[0]}=${p[1]}`)
.join('&');
query = query ? `?${query}` : '';
return `${protocol}:${path}${query}`;
}
exports.getChainUri = getChainUri;
/**
* Parse the chain resource URI into an object
* - `evm:mainnet?rpcUrl=...`
* - `evm:1`
* - `near:testnet`
* @param uri - Chain resource uri
*/
function parseChainUri(uri) {
debug('Parsing chain uri: %s', uri);
const url = new URL(uri);
// The protocol is `evm:` or `near:`
const type = url.protocol.replace(/\:$/, '');
let parts = (url.hostname + url.pathname).split('/').filter(p => p !== '');
let network = parts[0];
let chainId = undefined;
if (!isNaN(parseInt(network))) {
chainId = network;
network = '';
}
const query = {};
url.searchParams.forEach((val, key) => {
query[key] = val;
});
parts = parts.slice(1);
const chainResource = {
type,
network,
chainId,
path: parts.join('/'),
params: query,
};
const rpcUrl = query.rpcUrl;
if (rpcUrl != null) {
chainResource.rpcUrl = rpcUrl;
delete query.rpcUrl;
}
const indexerUrl = query.indexerUrl;
if (indexerUrl != null) {
chainResource.indexerUrl = indexerUrl;
delete query.indexerUrl;
}
if (chainId == null) {
delete chainResource.chainId;
}
if (parts.length) {
if (parts[0].includes(':')) {
const [tokenSpec, address] = parts[0].split(':');
chainResource.contract = {
address,
tokenSpec: tokenSpec.toUpperCase(),
};
if (parts[1] != null) {
chainResource.tokenId = parts[1];
}
}
else {
chainResource.account = parts[0];
}
}
debug('Chain resource: %O', chainResource);
return chainResource;
}
exports.parseChainUri = parseChainUri;
exports.NATIVE_TOKEN = {

@@ -22,0 +124,0 @@ address: '',

6

package.json
{
"name": "@collabland/chain",
"version": "0.2.6",
"version": "0.3.0",
"description": "CollabLand Ethereum Integration",

@@ -34,3 +34,3 @@ "main": "dist/index.js",

"dependencies": {
"@collabland/common": "^0.19.0",
"@collabland/common": "^0.19.1",
"tslib": "^2.0.0"

@@ -48,3 +48,3 @@ },

"author": "Abridged, Inc.",
"gitHead": "dfe21db5afbbf30e277790168914a23cdd54df3b"
"gitHead": "e0944f19fecd734aa41d1522059cb7c48137a37d"
}

@@ -22,2 +22,9 @@ // Copyright Abridged, Inc. 2021. All Rights Reserved.

/**
* Base chain connector
*
* @typeParam AMT - Amount type
* @typeParam TID - Token id type
* @typeParam M - Token metadata type
*/
export abstract class BaseChainConnector<

@@ -30,7 +37,32 @@ AMT = Amount,

abstract chainType: ChainType;
/**
* Native currency of the chain
*/
abstract nativeCurrency: NativeCurrency;
/**
* Check if the token spec is for NFT
* @param tokenSpec - Token spec
*/
abstract isNFT(tokenSpec: string): boolean;
/**
* Check if the token spec is for FT
* @param tokenSpec - Token spec
*/
abstract isFT(tokenSpec: string): boolean;
abstract getAmount(val: number | string): AMT;
/**
* Convert the value to `AMT`
* @param val - Value
*/
abstract toAmount(val: number | string | AMT): AMT;
/**
* Convert the token id to `TID`
* @param id
*/
abstract toTokenId(id: number | string | TID): TID;
protected concurrency = 4;

@@ -62,6 +94,11 @@

account: string,
...requests: AssetRequest<TID>[]
...requests: AssetRequest<TID | string | number>[]
): Promise<AssetResponse<AMT, TID, M>[]> {
const assetRequests: AssetRequest<TID>[] = requests.map(r => ({
address: r.address,
tokenSpec: r.tokenSpec,
tokenType: r.tokenType != null ? this.toTokenId(r.tokenType) : undefined,
}));
const assets = pMap(
requests,
assetRequests,
async req => {

@@ -88,3 +125,3 @@ let asset: AssetResponse<AMT, TID, M>;

);
asset = {balance: this.getAmount(nfts.length), tokens: nfts, ...req};
asset = {balance: this.toAmount(nfts.length), tokens: nfts, ...req};
return asset;

@@ -91,0 +128,0 @@ }

@@ -6,2 +6,5 @@ // Copyright Abridged, Inc. 2021. All Rights Reserved.

import {debugFactory} from '@collabland/common';
const debug = debugFactory('collabland:chain');
/**

@@ -22,6 +25,25 @@ * Chain type

export interface Chain {
type: ChainType;
/**
* Block chain type
*/
type: ChainType | string;
/**
* Chain id
*/
chainId?: string;
/**
* Chain network
*/
network: string;
/**
* RPC URL
*/
rpcUrl?: string;
/**
* Indexer URL
*/
indexerUrl?: string;

@@ -31,2 +53,135 @@ }

/**
* A blockchain resource
*/
export interface ChainResource extends Chain {
/**
* Extra parameters
*/
params?: Record<string, string>;
/**
* The resource path
*/
path?: string;
/**
* Account address or name
*/
account?: string;
/**
* Token contract
*/
contract?: TokenContract;
/**
* Token id
*/
tokenId?: string;
}
/**
* Get the uri for a given chain resource in the form of
* - `evm:mainnet/<account>`
* - `evm:mainnet/erc20/<erc20-contract-address>`
* - `evm:mainnet/erc721/<erc721-contract-address>/<token-id>`
*
* Inspired by https://github.com/ChainAgnostic/CAIPs
*
* @param chainResource - Chain resource
* @returns
*/
export function getChainUri(chainResource: ChainResource) {
const protocol = chainResource.type;
const path = [
chainResource.chainId ?? chainResource.network,
chainResource.path ??
chainResource.account ??
(chainResource.contract
? `${chainResource.contract.tokenSpec.toLowerCase()}:${
chainResource.contract.address
}`
: ''),
chainResource.tokenId ?? '',
]
.filter(p => !!p)
.join('/');
const params = chainResource.params ?? {};
if (chainResource.rpcUrl) {
params.rpcUrl = chainResource.rpcUrl;
}
if (chainResource.indexerUrl) {
params.indexerUrl = chainResource.indexerUrl;
}
let query = Object.entries(params)
.map(p => `${p[0]}=${p[1]}`)
.join('&');
query = query ? `?${query}` : '';
return `${protocol}:${path}${query}`;
}
/**
* Parse the chain resource URI into an object
* - `evm:mainnet?rpcUrl=...`
* - `evm:1`
* - `near:testnet`
* @param uri - Chain resource uri
*/
export function parseChainUri(uri: string): ChainResource {
debug('Parsing chain uri: %s', uri);
const url = new URL(uri);
// The protocol is `evm:` or `near:`
const type = url.protocol.replace(/\:$/, '') as ChainType;
let parts = (url.hostname + url.pathname).split('/').filter(p => p !== '');
let network = parts[0];
let chainId = undefined;
if (!isNaN(parseInt(network))) {
chainId = network;
network = '';
}
const query: Record<string, string> = {};
url.searchParams.forEach((val, key) => {
query[key] = val;
});
parts = parts.slice(1);
const chainResource: ChainResource = {
type,
network,
chainId,
path: parts.join('/'),
params: query,
};
const rpcUrl = query.rpcUrl;
if (rpcUrl != null) {
chainResource.rpcUrl = rpcUrl;
delete query.rpcUrl;
}
const indexerUrl = query.indexerUrl;
if (indexerUrl != null) {
chainResource.indexerUrl = indexerUrl;
delete query.indexerUrl;
}
if (chainId == null) {
delete chainResource.chainId;
}
if (parts.length) {
if (parts[0].includes(':')) {
const [tokenSpec, address] = parts[0].split(':');
chainResource.contract = {
address,
tokenSpec: tokenSpec.toUpperCase(),
};
if (parts[1] != null) {
chainResource.tokenId = parts[1];
}
} else {
chainResource.account = parts[0];
}
}
debug('Chain resource: %O', chainResource);
return chainResource;
}
/**
* Default type for amount

@@ -187,3 +342,3 @@ */

account: string,
...requests: AssetRequest<TID>[]
...requests: AssetRequest<TID | string | number>[]
): Promise<AssetResponse<AMT, TID, M>[]>;

@@ -190,0 +345,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc