Skip to content

Commit

Permalink
Merge pull request #69 from Peach2Peach/feature/add-peek
Browse files Browse the repository at this point in the history
Feature/add peek
  • Loading branch information
BitcoinZavior authored Nov 21, 2023
2 parents 930a6bc + 84ae5a1 commit 37b33a8
Show file tree
Hide file tree
Showing 13 changed files with 107 additions and 36 deletions.
23 changes: 19 additions & 4 deletions __tests__/classes/Wallet.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Address, Blockchain, DatabaseConfig, Descriptor, PartiallySignedTransaction, Wallet } from '../../src';
import { AddressIndex, KeychainKind, Network } from '../../src/lib/enums';
import { AddressInfo, Balance, LocalUtxo, SignOptions } from '../../src/classes/Bindings';
import { changeDescriptorString, descriptorString, mockTransactionDetails } from '../mockData';
import { createOutpoint, createTxOut } from '../../src/lib/utils';

import { Script } from '../../src/classes/Script';
import { AddressIndex, KeychainKind, Network } from '../../src/lib/enums';
import { createOutpoint, createTxOut } from '../../src/lib/utils';
import { changeDescriptorString, descriptorString, mockTransactionDetails } from '../mockData';
import { mockBdkRnModule } from '../setup';

describe('Wallet', () => {
Expand Down Expand Up @@ -67,6 +66,14 @@ describe('Wallet', () => {
expect(mockBdkRnModule.getAddress).toHaveBeenCalledWith(wallet.id, AddressIndex.LastUnused);
});

it('Should return AddressInfo at index using the external descriptor', async () => {
const index = 21;
let res = await wallet.getAddress(index);
expect(res.index).toBe(addressIndex);
expect(res.address).toStrictEqual(new Address()._setAddress(address));
expect(mockBdkRnModule.getAddress).toHaveBeenCalledWith(wallet.id, index);
});

it('Should return a new AddressInfo using the internal descriptor', async () => {
let res = await wallet.getInternalAddress(AddressIndex.New);
expect(res).toBeInstanceOf(AddressInfo);
Expand All @@ -82,6 +89,14 @@ describe('Wallet', () => {
expect(mockBdkRnModule.getInternalAddress).toHaveBeenCalledWith(wallet.id, AddressIndex.LastUnused);
});

it('Should return AddressInfo at index using the internal descriptor', async () => {
const index = 21;
let res = await wallet.getInternalAddress(index);
expect(res.index).toBe(addressIndex);
expect(res.address).toStrictEqual(new Address()._setAddress(address));
expect(mockBdkRnModule.getInternalAddress).toHaveBeenCalledWith(wallet.id, index);
});

it('Should return valid Balance object', async () => {
const mockedNumber = 150;
const expectedBalance = new Balance(mockedNumber, mockedNumber, mockedNumber, mockedNumber, mockedNumber);
Expand Down
35 changes: 30 additions & 5 deletions android/src/main/java/io/ltbl/bdkrn/BdkRnModule.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.ltbl.bdkrn

import com.facebook.react.bridge.*
import com.facebook.react.bridge.ReadableType
import com.facebook.react.bridge.Dynamic
import com.facebook.react.bridge.UiThreadUtil.runOnUiThread
import org.bitcoindevkit.*
import org.bitcoindevkit.Descriptor.Companion.newBip44
Expand Down Expand Up @@ -380,11 +382,23 @@ class BdkRnModule(reactContext: ReactApplicationContext) :
}

@ReactMethod
fun getAddress(id: String, addressIndex: String, result: Promise) {
fun getAddress(id: String, addressIndex: Dynamic, result: Promise) {
Thread {
try {
val randomId = randomId()
val addressInfo = getWalletById(id).getAddress(setAddressIndex(addressIndex))
var resolvedIndex: Any = "new"
when (val type = addressIndex.getType()) {
ReadableType.String -> {
resolvedIndex = (addressIndex as Dynamic).asString() ?: "new"
}
ReadableType.Number -> {
resolvedIndex = (addressIndex as Dynamic).asDouble() ?: "new"
}
else -> {
resolvedIndex = setAddressIndex("new")
}
}
val addressInfo = getWalletById(id).getAddress(setAddressIndex(resolvedIndex))
_addresses[randomId] = addressInfo.address
val responseObject = mutableMapOf<String, Any?>()
responseObject["index"] = addressInfo.index.toInt()
Expand All @@ -398,12 +412,23 @@ class BdkRnModule(reactContext: ReactApplicationContext) :
}

@ReactMethod
fun getInternalAddress(id: String, addressIndex: String, result: Promise) {
fun getInternalAddress(id: String, addressIndex: Dynamic, result: Promise) {
Thread {
try {
val randomId = randomId()
val addressInfo =
getWalletById(id).getInternalAddress(setAddressIndex(addressIndex))
var resolvedIndex: Any = "new"
when (val type = addressIndex.getType()) {
ReadableType.String -> {
resolvedIndex = (addressIndex as Dynamic).asString() ?: "new"
}
ReadableType.Number -> {
resolvedIndex = (addressIndex as Dynamic).asDouble() ?: "new"
}
else -> {
resolvedIndex = setAddressIndex("new")
}
}
val addressInfo = getWalletById(id).getInternalAddress(setAddressIndex(resolvedIndex))
_addresses[randomId] = addressInfo.address
val responseObject = mutableMapOf<String, Any?>()
responseObject["index"] = addressInfo.index.toInt()
Expand Down
12 changes: 9 additions & 3 deletions android/src/main/java/io/ltbl/bdkrn/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,16 @@ fun getEntropy(entropy: ReadableArray): List<UByte> {
return entropyArray
}

fun setAddressIndex(addressIndex: String?): AddressIndex {
fun setAddressIndex(addressIndex: Any?): AddressIndex {
return when (addressIndex) {
"new" -> return AddressIndex.New
"lastUnused" -> return AddressIndex.LastUnused
is String -> when (addressIndex) {
"new" -> AddressIndex.New
"lastUnused" -> AddressIndex.LastUnused
else -> AddressIndex.New
}
is Double -> {
AddressIndex.Peek(addressIndex.toUInt())
}
else -> AddressIndex.New
}
}
Expand Down
4 changes: 2 additions & 2 deletions ios/BdkRnModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,14 @@ @interface RCT_EXTERN_MODULE(BdkRnModule, NSObject)

RCT_EXTERN_METHOD(
getAddress:(nonnull NSString*)id
addressIndex: (nonnull NSString*)addressIndex
addressIndex: (nonnull id)addressIndex
resolve: (RCTPromiseResolveBlock)resolve
reject: (RCTPromiseRejectBlock)reject
)

RCT_EXTERN_METHOD(
getInternalAddress:(nonnull NSString*)id
addressIndex: (nonnull NSString*)addressIndex
addressIndex: (nonnull id)addressIndex
resolve: (RCTPromiseResolveBlock)resolve
reject: (RCTPromiseRejectBlock)reject
)
Expand Down
25 changes: 21 additions & 4 deletions ios/BdkRnModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -490,13 +490,22 @@ class BdkRnModule: NSObject {
@objc
func getAddress(_
id: String,
addressIndex: String,
addressIndex: Any,
resolve: @escaping RCTPromiseResolveBlock,
reject: @escaping RCTPromiseRejectBlock
) {
do {
let resolvedIndex: AddressIndex
if let indexString = addressIndex as? String {
resolvedIndex = setAddressIndex(addressIndex: indexString)
} else if let indexInt = addressIndex as? Int {
resolvedIndex = setAddressIndex(addressIndex: indexInt)
} else {
resolvedIndex = setAddressIndex(addressIndex: "new")
}

let addressInfo = try getWalletById(id: id).getAddress(
addressIndex: setAddressIndex(addressIndex: addressIndex)
addressIndex: resolvedIndex
)
let randomId = randomId()
_addresses[randomId] = addressInfo.address
Expand All @@ -509,13 +518,21 @@ class BdkRnModule: NSObject {
@objc
func getInternalAddress(_
id: String,
addressIndex: String,
addressIndex: Any,
resolve: @escaping RCTPromiseResolveBlock,
reject: @escaping RCTPromiseRejectBlock
) {
do {
let resolvedIndex: AddressIndex
if let indexString = addressIndex as? String {
resolvedIndex = setAddressIndex(addressIndex: indexString)
} else if let indexInt = addressIndex as? Int {
resolvedIndex = setAddressIndex(addressIndex: indexInt)
} else {
resolvedIndex = setAddressIndex(addressIndex: "new")
}
let addressInfo = try getWalletById(id: id).getInternalAddress(
addressIndex: setAddressIndex(addressIndex: addressIndex)
addressIndex: resolvedIndex
)
let randomId = randomId()
_addresses[randomId] = addressInfo.address
Expand Down
19 changes: 14 additions & 5 deletions ios/Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,20 @@ func getEntropy(entropy: NSArray) -> Array<UInt8> {
}


func setAddressIndex(addressIndex: String?) -> AddressIndex {
switch (addressIndex) {
case "new": return AddressIndex.new
case "lastUnused": return AddressIndex.lastUnused
default: return AddressIndex.new
func setAddressIndex(addressIndex: Any?) -> AddressIndex {
if let addressIndexString = addressIndex as? String {
switch addressIndexString {
case "new":
return AddressIndex.new
case "lastUnused":
return AddressIndex.lastUnused
default:
return AddressIndex.new
}
} else if let addressIndexNumber = addressIndex as? Int {
return AddressIndex.peek(index: UInt32(addressIndexNumber))
} else {
return AddressIndex.new
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/classes/NativeLoader.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface NativeBdkRn {
sqliteDBInit(path: string): string;
walletInit(descriptor: string, changeDescriptor: string | null, network: Network, dbConfig: string): any;
getAddress(id: string, addressIndex: AddressIndex): any;
getInternalAddress(id: string, addressIndex: AddressIndex): any;
getInternalAddress(id: string, addressIndex: AddressIndex | number): any;
isMine(id: string, scriptId: string): boolean;
getBalance(id: string): Balance;
getNetwork(id: string): string;
Expand Down
2 changes: 1 addition & 1 deletion lib/classes/NativeLoader.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/classes/Wallet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export declare class Wallet extends NativeLoader {
* @param addressIndex
* @returns {Promise<AddressInfo>}
*/
getInternalAddress(addressIndex: AddressIndex): Promise<AddressInfo>;
getInternalAddress(addressIndex: AddressIndex | number): Promise<AddressInfo>;
/**
* check if the wallet is yours or not
* @param script
Expand Down
2 changes: 1 addition & 1 deletion lib/classes/Wallet.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/classes/Wallet.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions src/classes/NativeLoader.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { NativeModules } from 'react-native';

import { AddressIndex, BlockchainRpcConfig, KeychainKind, Network, Payload, WordCount } from '../lib/enums';
import { Balance, OutPoint, ScriptAmount, SignOptions, TransactionDetails } from './Bindings';

import { NativeModules } from 'react-native';

export interface NativeBdkRn {
generateSeedFromWordCount(wordCount: WordCount): string;
generateSeedFromString(mnemonic: string): string;
Expand Down Expand Up @@ -50,8 +50,8 @@ export interface NativeBdkRn {
sqliteDBInit(path: string): string;

walletInit(descriptor: string, changeDescriptor: string | null, network: Network, dbConfig: string): any;
getAddress(id: string, addressIndex: AddressIndex): any;
getInternalAddress(id: string, addressIndex: AddressIndex): any;
getAddress(id: string, addressIndex: AddressIndex | number): any;
getInternalAddress(id: string, addressIndex: AddressIndex | number): any;
isMine(id: string, scriptId: string): boolean;
getBalance(id: string): Balance;
getNetwork(id: string): string;
Expand Down
7 changes: 3 additions & 4 deletions src/classes/Wallet.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { AddressIndex, Network } from '../lib/enums';
import { AddressInfo, Balance, LocalUtxo, SignOptions, TransactionDetails } from './Bindings';
import { createOutpoint, createTxDetailsObject, createTxOut, getKeychainKind, getNetwork } from '../lib/utils';

import { Address } from './Address';
import { AddressInfo, Balance, LocalUtxo, SignOptions, TransactionDetails } from './Bindings';
import { Blockchain } from './Blockchain';
import { DatabaseConfig } from './DatabaseConfig';
import { Descriptor } from './Descriptor';
Expand Down Expand Up @@ -44,7 +43,7 @@ export class Wallet extends NativeLoader {
* @param addressIndex
* @returns {Promise<AddressInfo>}
*/
async getAddress(addressIndex: AddressIndex): Promise<AddressInfo> {
async getAddress(addressIndex: AddressIndex | number): Promise<AddressInfo> {
let addressInfo = await this._bdk.getAddress(this.id, addressIndex);
return new AddressInfo(
addressInfo.index,
Expand All @@ -58,7 +57,7 @@ export class Wallet extends NativeLoader {
* @param addressIndex
* @returns {Promise<AddressInfo>}
*/
async getInternalAddress(addressIndex: AddressIndex): Promise<AddressInfo> {
async getInternalAddress(addressIndex: AddressIndex | number): Promise<AddressInfo> {
let addressInfo = await this._bdk.getInternalAddress(this.id, addressIndex);
return new AddressInfo(
addressInfo.index,
Expand Down

0 comments on commit 37b33a8

Please sign in to comment.