Skip to content

Commit 327b2d6

Browse files
cheeseandcerealWingman4l7
authored andcommitted
Release 4.1.0 (#11)
* Issue 7: Erroneous "?" (#8) * return empty string if no query parameters are provided * Adding Binance integration. (#10) * Fixed bug & added Binance support.
1 parent 7e36ff6 commit 327b2d6

File tree

5 files changed

+222
-9
lines changed

5 files changed

+222
-9
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## 4.1.0
4+
5+
- **Feature:**
6+
7+
- Add support for new Binance interchain endpoints with client functions:
8+
- `createBinanceInterchain`
9+
- `updateBinanceInterchain`
10+
- `signBinanceTransaction`
11+
12+
- **Bug Fix**
13+
- Remove erroneous `?` from query string when no query string parameters are provided
14+
- Fix typing bug with `getSmartContractObject`
15+
316
## 4.0.0
417

518
Because Dragonchain has a breaking change to replace its indexing solution, this is also a breaking SDK change for queries and custom indexing.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dragonchain-sdk",
3-
"version": "4.0.0",
3+
"version": "4.1.0",
44
"description": "Dragonchain SDK for Node.JS and the Browser",
55
"license": "Apache-2.0",
66
"homepage": "https://github.com/dragonchain/dragonchain-sdk-javascript#readme",

src/interfaces/DragonchainClientInterfaces.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export interface PublicBlockchainTransactionResponse {
221221
signed: string;
222222
}
223223

224-
export type SupportedInterchains = 'ethereum' | 'bitcoin';
224+
export type SupportedInterchains = 'ethereum' | 'bitcoin' | 'binance';
225225

226226
/**
227227
* @example
@@ -255,7 +255,7 @@ export interface EthereumInterchainNetwork {
255255
* "blockchain": "bitcoin",
256256
* "name": "myBTCTestNetwork",
257257
* "rpc_address": "http://1.2.3.4:18332",
258-
* "tesnet": true,
258+
* "testnet": true,
259259
* "address": "n1bUzF6LRENLPaiJRFTcnGLMLsbZSquft1"
260260
* }
261261
* ```
@@ -269,6 +269,32 @@ export interface BitcoinInterchainNetwork {
269269
address: string;
270270
}
271271

272+
/**
273+
* @example
274+
* ```json
275+
*
276+
* {
277+
* "version": "1",
278+
* "blockchain": "binance",
279+
* "name": "myBNBTestNetwork",
280+
* "testnet": True,
281+
* "node_url": "http://1.2.3.4",
282+
* "rpc_port": 26657,
283+
* "api_port": 11699,
284+
* "address": "tbnb1zesqcktldshz7tat9u74duc037frzwvdq83wan"
285+
* }
286+
* ```
287+
*/
288+
export interface BinanceInterchainNetwork {
289+
version: string;
290+
blockchain: 'binance';
291+
name: string;
292+
node_url: string;
293+
rpc_port: number;
294+
api_port: number;
295+
address: string;
296+
}
297+
272298
/**
273299
* Array of interchains will be all of one type
274300
* @example
@@ -287,7 +313,7 @@ export interface BitcoinInterchainNetwork {
287313
* ```
288314
*/
289315
export interface InterchainNetworkList {
290-
interchains: BitcoinInterchainNetwork[] | EthereumInterchainNetwork[];
316+
interchains: BitcoinInterchainNetwork[] | EthereumInterchainNetwork[] | BinanceInterchainNetwork[];
291317
}
292318

293319
/**

src/services/dragonchain-client/DragonchainClient.spec.ts

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ describe('DragonchainClient', () => {
198198
await client.getSmartContractLogs({ smartContractId: 'test', tail: 100, since: 'a-date' });
199199
assert.calledWith(fetch, `fakeUrl/v1/contract/test/logs?tail=100&since=a-date`, expectedFetchOptions);
200200
});
201+
202+
it('calls #fetch() with correct params and missing erroneous ?', async () => {
203+
await client.getSmartContractLogs({ smartContractId: 'test' });
204+
assert.calledWith(fetch, `fakeUrl/v1/contract/test/logs`, expectedFetchOptions);
205+
});
201206
});
202207

203208
describe('.getInterchainNetwork', () => {
@@ -420,6 +425,23 @@ describe('DragonchainClient', () => {
420425
});
421426
});
422427

428+
describe('.createBinanceInterchain', () => {
429+
it('calls #fetch() with correct params', async () => {
430+
const fakeBody: any = {
431+
version: '1',
432+
name: 'banana',
433+
testnet: true,
434+
private_key: 'abcd',
435+
node_url: 'some IP',
436+
rpc_port: 1234,
437+
api_port: 5678
438+
};
439+
await client.createBinanceInterchain({ name: 'banana', testnet: true, privateKey: 'abcd', nodeURL: 'some IP', rpcPort: 1234, apiPort: 5678 });
440+
const obj = { ...expectedFetchOptions, body: JSON.stringify(fakeBody) };
441+
assert.calledWith(fetch, 'fakeUrl/v1/interchains/binance', obj);
442+
});
443+
});
444+
423445
describe('.signBitcoinTransaction', () => {
424446
it('calls #fetch() with correct params', async () => {
425447
const fakeBody: any = {
@@ -452,6 +474,21 @@ describe('DragonchainClient', () => {
452474
});
453475
});
454476

477+
describe('.signBinanceTransaction', () => {
478+
it('calls #fetch() with correct params', async () => {
479+
const fakeBody: any = {
480+
version: '1',
481+
amount: 123,
482+
to_address: 'receiver addy',
483+
symbol: 'TOKEN',
484+
memo: 'for bananas'
485+
};
486+
await client.signBinanceTransaction({ name: 'banana', amount: 123, toAddress: 'receiver addy', symbol: 'TOKEN', memo: 'for bananas' });
487+
const obj = { ...expectedFetchOptions, body: JSON.stringify(fakeBody) };
488+
assert.calledWith(fetch, 'fakeUrl/v1/interchains/binance/banana/transaction', obj);
489+
});
490+
});
491+
455492
describe('.setDefaultInterchainNetwork', () => {
456493
it('calls #fetch() with correct params', async () => {
457494
const fakeBody: any = {
@@ -541,14 +578,30 @@ describe('DragonchainClient', () => {
541578
it('calls #fetch() with correct params', async () => {
542579
const fakeBody: any = {
543580
version: '1',
544-
private_key: 'private key',
581+
private_key: 'abcd',
545582
rpc_address: 'some rpc',
546583
chain_id: 12
547584
};
548-
await client.updateEthereumInterchain({ name: 'banana', privateKey: 'private key', rpcAddress: 'some rpc', chainId: 12 });
585+
await client.updateEthereumInterchain({ name: 'banana', privateKey: 'abcd', rpcAddress: 'some rpc', chainId: 12 });
549586
const obj = { ...expectedFetchOptions, body: JSON.stringify(fakeBody) };
550587
assert.calledWith(fetch, 'fakeUrl/v1/interchains/ethereum/banana', obj);
551588
});
552589
});
590+
591+
describe('.updateBinanceInterchain', () => {
592+
it('calls #fetch() with correct params', async () => {
593+
const fakeBody: any = {
594+
version: '1',
595+
testnet: true,
596+
private_key: 'abcd',
597+
node_url: 'some IP',
598+
rpc_port: 1234,
599+
api_port: 5678
600+
};
601+
await client.updateBinanceInterchain({ name: 'banana', testnet: true, privateKey: 'abcd', nodeURL: 'some IP', rpcPort: 1234, apiPort: 5678 });
602+
const obj = { ...expectedFetchOptions, body: JSON.stringify(fakeBody) };
603+
assert.calledWith(fetch, 'fakeUrl/v1/interchains/binance/banana', obj);
604+
});
605+
});
553606
});
554607
});

src/services/dragonchain-client/DragonchainClient.ts

Lines changed: 124 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
DeleteAPIKeyResponse,
4949
EthereumInterchainNetwork,
5050
BitcoinInterchainNetwork,
51+
BinanceInterchainNetwork,
5152
SupportedInterchains,
5253
InterchainNetworkList,
5354
CustomTextFieldOptions,
@@ -748,8 +749,7 @@ export class DragonchainClient {
748749
if (!process.env.SMART_CONTRACT_ID) throw new FailureByDesign('PARAM_ERROR', 'Parameter `smartContractId` is required when not running within a smart contract');
749750
options.smartContractId = process.env.SMART_CONTRACT_ID;
750751
}
751-
const response = (await this.get(`/v1/get/${options.smartContractId}/${options.key}`, false)) as unknown;
752-
return response as string;
752+
return (await this.get(`/v1/get/${options.smartContractId}/${options.key}`, false)) as Response<string>;
753753
};
754754

755755
/**
@@ -1076,6 +1076,127 @@ export class DragonchainClient {
10761076
return (await this.post(`/v1/interchains/ethereum/${options.name}/transaction`, body)) as Response<PublicBlockchainTransactionResponse>;
10771077
};
10781078

1079+
/**
1080+
* Create (or overwrite) a binance wallet/network for interchain use
1081+
*/
1082+
1083+
public createBinanceInterchain = async (options: {
1084+
/**
1085+
* The name of the network to update
1086+
*/
1087+
name: string;
1088+
/**
1089+
* Whether or not this is a testnet wallet/address. Defaults to True.
1090+
*/
1091+
testnet?: boolean;
1092+
/**
1093+
* The base64 or hex encoded private key (or mnemonic) to use. Will automatically generate a random one if not provided
1094+
*/
1095+
privateKey?: string;
1096+
/**
1097+
* The endpoint of the binance node to use (i.e. http://my.node.address)
1098+
*/
1099+
nodeURL?: string;
1100+
/**
1101+
* The port being used to hit the RPC endpoints (i.e. 27147)
1102+
*/
1103+
rpcPort?: number;
1104+
/**
1105+
* The port being used to hit the API endpoints (i.e. 1169)
1106+
*/
1107+
apiPort?: number;
1108+
}) => {
1109+
if (!options.name) throw new FailureByDesign('PARAM_ERROR', 'Parameter `name` is required');
1110+
if (options.rpcPort && !Number.isInteger(options.rpcPort)) throw new FailureByDesign('PARAM_ERROR', 'Parameter `rpcPort` must be an integer');
1111+
if (options.apiPort && !Number.isInteger(options.apiPort)) throw new FailureByDesign('PARAM_ERROR', 'Parameter `apiPort` must be an integer');
1112+
const body: any = { version: '1', name: options.name };
1113+
if (typeof options.testnet === 'boolean') body.testnet = options.testnet;
1114+
if (options.privateKey) body.private_key = options.privateKey;
1115+
if (options.nodeURL) body.node_url = options.nodeURL;
1116+
if (options.rpcPort) body.rpc_port = options.rpcPort;
1117+
if (options.rpcPort) body.api_port = options.apiPort;
1118+
return (await this.post(`/v1/interchains/binance`, body)) as Response<BinanceInterchainNetwork>;
1119+
};
1120+
1121+
/**
1122+
* Update an existing binance wallet/network for interchain use
1123+
*/
1124+
public updateBinanceInterchain = async (options: {
1125+
/**
1126+
* The name of the network to update
1127+
*/
1128+
name: string;
1129+
/**
1130+
* Whether or not this is a testnet wallet/address. Defaults to True.
1131+
*/
1132+
testnet?: boolean;
1133+
/**
1134+
* The base64 or hex encoded private key to use. Will automatically generate a random one if not provided
1135+
*/
1136+
privateKey?: string;
1137+
/**
1138+
* The endpoint of the binance node to use (i.e. http://my.node.address)
1139+
*/
1140+
nodeURL?: string;
1141+
/**
1142+
* The port being used to hit the RPC endpoints (i.e. 27147)
1143+
*/
1144+
rpcPort?: number;
1145+
/**
1146+
* The port being used to hit the API endpoints (i.e. 1169)
1147+
*/
1148+
apiPort?: number;
1149+
}) => {
1150+
if (!options.name) throw new FailureByDesign('PARAM_ERROR', 'Parameter `name` is required');
1151+
if (options.rpcPort && !Number.isInteger(options.rpcPort)) throw new FailureByDesign('PARAM_ERROR', 'Parameter `rpcPort` must be an integer');
1152+
if (options.apiPort && !Number.isInteger(options.apiPort)) throw new FailureByDesign('PARAM_ERROR', 'Parameter `apiPort` must be an integer');
1153+
const body: any = { version: '1' };
1154+
if (typeof options.testnet === 'boolean') body.testnet = options.testnet;
1155+
if (options.privateKey) body.private_key = options.privateKey;
1156+
if (options.nodeURL) body.node_url = options.nodeURL;
1157+
if (options.rpcPort) body.rpc_port = options.rpcPort;
1158+
if (options.apiPort) body.api_port = options.apiPort;
1159+
return (await this.patch(`/v1/interchains/binance/${options.name}`, body)) as Response<BinanceInterchainNetwork>;
1160+
};
1161+
1162+
/**
1163+
* Create and sign a binance transaction using your chain's interchain network
1164+
*/
1165+
public signBinanceTransaction = async (options: {
1166+
/**
1167+
* The name of the binance network to use for signing
1168+
*/
1169+
name: string;
1170+
/**
1171+
* the amount of token to send with this transaction
1172+
*/
1173+
amount: number;
1174+
/**
1175+
* The (hex-encoded) address to send the transaction to
1176+
*/
1177+
toAddress: string;
1178+
/**
1179+
* the exchange symbol for the token (defaults to BNB)
1180+
*/
1181+
symbol?: string;
1182+
/**
1183+
* string of data to publish in the transaction (defaults to "")
1184+
*/
1185+
memo?: string;
1186+
}) => {
1187+
if (!options.name) throw new FailureByDesign('PARAM_ERROR', 'Parameter `name` is required');
1188+
if (!options.amount) throw new FailureByDesign('PARAM_ERROR', 'Parameter `amount` is required');
1189+
if (!options.toAddress) throw new FailureByDesign('PARAM_ERROR', 'Parameter `toAddress` is required');
1190+
const body: any = {
1191+
version: '1',
1192+
amount: options.amount,
1193+
to_address: options.toAddress
1194+
};
1195+
if (options.symbol) body.symbol = options.symbol;
1196+
if (options.memo) body.memo = options.memo;
1197+
return (await this.post(`/v1/interchains/binance/${options.name}/transaction`, body)) as Response<PublicBlockchainTransactionResponse>;
1198+
};
1199+
10791200
/**
10801201
* Get a configured interchain network/wallet from the chain
10811202
*/
@@ -1347,7 +1468,7 @@ export class DragonchainClient {
13471468
/**
13481469
* @hidden
13491470
*/
1350-
private generateQueryString = (queryObject: Map<string, string | number>) => `?${UrlSearchParams(queryObject)}`;
1471+
private generateQueryString = (queryObject: Map<string, string | number>) => (Object.keys(queryObject).length > 0 ? `?${UrlSearchParams(queryObject)}` : '');
13511472

13521473
/**
13531474
* @hidden

0 commit comments

Comments
 (0)