@reown/appkit-bitcoin-react-native 0.0.0-canary-20251008180350

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/lib/commonjs/adapter.js +104 -0
  2. package/lib/commonjs/adapter.js.map +1 -0
  3. package/lib/commonjs/index.js +13 -0
  4. package/lib/commonjs/index.js.map +1 -0
  5. package/lib/commonjs/package.json +1 -0
  6. package/lib/commonjs/utils/BitcoinApi.js +25 -0
  7. package/lib/commonjs/utils/BitcoinApi.js.map +1 -0
  8. package/lib/commonjs/utils/FormatUtil.js +37 -0
  9. package/lib/commonjs/utils/FormatUtil.js.map +1 -0
  10. package/lib/commonjs/utils/UnitsUtil.js +15 -0
  11. package/lib/commonjs/utils/UnitsUtil.js.map +1 -0
  12. package/lib/module/adapter.js +99 -0
  13. package/lib/module/adapter.js.map +1 -0
  14. package/lib/module/index.js +5 -0
  15. package/lib/module/index.js.map +1 -0
  16. package/lib/module/utils/BitcoinApi.js +21 -0
  17. package/lib/module/utils/BitcoinApi.js.map +1 -0
  18. package/lib/module/utils/FormatUtil.js +33 -0
  19. package/lib/module/utils/FormatUtil.js.map +1 -0
  20. package/lib/module/utils/UnitsUtil.js +11 -0
  21. package/lib/module/utils/UnitsUtil.js.map +1 -0
  22. package/lib/typescript/adapter.d.ts +13 -0
  23. package/lib/typescript/adapter.d.ts.map +1 -0
  24. package/lib/typescript/index.d.ts +3 -0
  25. package/lib/typescript/index.d.ts.map +1 -0
  26. package/lib/typescript/utils/BitcoinApi.d.ts +23 -0
  27. package/lib/typescript/utils/BitcoinApi.d.ts.map +1 -0
  28. package/lib/typescript/utils/FormatUtil.d.ts +7 -0
  29. package/lib/typescript/utils/FormatUtil.d.ts.map +1 -0
  30. package/lib/typescript/utils/UnitsUtil.d.ts +5 -0
  31. package/lib/typescript/utils/UnitsUtil.d.ts.map +1 -0
  32. package/package.json +50 -0
  33. package/readme.md +9 -0
  34. package/src/adapter.ts +114 -0
  35. package/src/index.tsx +2 -0
  36. package/src/utils/BitcoinApi.ts +41 -0
  37. package/src/utils/FormatUtil.ts +33 -0
  38. package/src/utils/UnitsUtil.ts +11 -0
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.BitcoinAdapter = void 0;
7
+ var _appkitCommonReactNative = require("@reown/appkit-common-react-native");
8
+ var _BitcoinApi = require("./utils/BitcoinApi");
9
+ var _UnitsUtil = require("./utils/UnitsUtil");
10
+ var _FormatUtil = require("./utils/FormatUtil");
11
+ class BitcoinAdapter extends _appkitCommonReactNative.BitcoinBaseAdapter {
12
+ static supportedNamespace = 'bip122';
13
+ static api = _BitcoinApi.BitcoinApi;
14
+ constructor() {
15
+ super({
16
+ supportedNamespace: BitcoinAdapter.supportedNamespace,
17
+ adapterType: 'bip122'
18
+ });
19
+ }
20
+ async getBalance(params) {
21
+ const {
22
+ network,
23
+ address
24
+ } = params;
25
+ if (!this.connector) throw new Error('No active connector');
26
+ if (!network) throw new Error('No network provided');
27
+ const balanceCaipAddress = address || this.getAccounts()?.find(account => account.includes(network.id.toString()));
28
+ const balanceAddress = balanceCaipAddress?.split(':')[2];
29
+ if (!balanceCaipAddress || !balanceAddress) {
30
+ return Promise.resolve({
31
+ amount: '0.00',
32
+ symbol: 'BTC'
33
+ });
34
+ }
35
+ try {
36
+ const utxos = await BitcoinAdapter.api.getUTXOs({
37
+ network,
38
+ address: balanceAddress
39
+ });
40
+ const balance = utxos.reduce((acc, utxo) => acc + utxo.value, 0);
41
+ const formattedBalance = _UnitsUtil.UnitsUtil.parseSatoshis(balance.toString(), network);
42
+ this.emit('balanceChanged', {
43
+ address: balanceCaipAddress,
44
+ balance: {
45
+ amount: formattedBalance,
46
+ symbol: network.nativeCurrency.symbol
47
+ }
48
+ });
49
+ return {
50
+ amount: formattedBalance,
51
+ symbol: network.nativeCurrency.symbol
52
+ };
53
+ } catch (error) {
54
+ return {
55
+ amount: '0.00',
56
+ symbol: 'BTC'
57
+ };
58
+ }
59
+ }
60
+ async switchNetwork(network) {
61
+ if (!this.connector) throw new Error('No active connector');
62
+ const provider = this.connector.getProvider('bip122');
63
+ if (!provider) throw new Error('No active provider');
64
+ try {
65
+ await this.connector.switchNetwork(network);
66
+ return;
67
+ } catch (switchError) {
68
+ throw switchError;
69
+ }
70
+ }
71
+ getAccounts() {
72
+ if (!this.connector) throw new Error('No active connector');
73
+ const namespaces = this.connector.getNamespaces();
74
+ return namespaces[this.getSupportedNamespace()]?.accounts;
75
+ }
76
+ disconnect() {
77
+ if (!this.connector) throw new Error('SolanaAdapter:disconnect - No active connector');
78
+ return this.connector.disconnect();
79
+ }
80
+ getSupportedNamespace() {
81
+ return BitcoinAdapter.supportedNamespace;
82
+ }
83
+ async signMessage(address, message, chainId) {
84
+ if (!this.connector) throw new Error('BitcoinAdapter:signMessage - No active connector');
85
+ const provider = this.connector.getProvider('bip122');
86
+ if (!provider) throw new Error('BitcoinAdapter:signMessage - No active provider');
87
+ const chain = chainId ? `${this.getSupportedNamespace()}:${chainId}` : undefined;
88
+ const {
89
+ signature
90
+ } = await provider.request({
91
+ method: 'signMessage',
92
+ params: {
93
+ message,
94
+ account: address,
95
+ address,
96
+ protocol: 'ecdsa'
97
+ }
98
+ }, chain);
99
+ const formattedSignature = _FormatUtil.FormatUtil.normalizeSignature(signature);
100
+ return formattedSignature.base64;
101
+ }
102
+ }
103
+ exports.BitcoinAdapter = BitcoinAdapter;
104
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_appkitCommonReactNative","require","_BitcoinApi","_UnitsUtil","_FormatUtil","BitcoinAdapter","BitcoinBaseAdapter","supportedNamespace","api","BitcoinApi","constructor","adapterType","getBalance","params","network","address","connector","Error","balanceCaipAddress","getAccounts","find","account","includes","id","toString","balanceAddress","split","Promise","resolve","amount","symbol","utxos","getUTXOs","balance","reduce","acc","utxo","value","formattedBalance","UnitsUtil","parseSatoshis","emit","nativeCurrency","error","switchNetwork","provider","getProvider","switchError","namespaces","getNamespaces","getSupportedNamespace","accounts","disconnect","signMessage","message","chainId","chain","undefined","signature","request","method","protocol","formattedSignature","FormatUtil","normalizeSignature","base64","exports"],"sourceRoot":"../../src","sources":["adapter.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "BitcoinAdapter", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _adapter.BitcoinAdapter;
10
+ }
11
+ });
12
+ var _adapter = require("./adapter");
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_adapter","require"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;AAAA,IAAAA,QAAA,GAAAC,OAAA","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.BitcoinApi = void 0;
7
+ var _appkitCommonReactNative = require("@reown/appkit-common-react-native");
8
+ const BitcoinApi = exports.BitcoinApi = {
9
+ getUTXOs: async ({
10
+ network,
11
+ address
12
+ }) => {
13
+ const isTestnet = network.caipNetworkId === _appkitCommonReactNative.bitcoinTestnet.caipNetworkId;
14
+ // Make chain dynamic
15
+
16
+ //TODO: Call rpc to get balance
17
+ const url = `https://mempool.space${isTestnet ? '/testnet' : ''}/api/address/${address}/utxo`;
18
+ const response = await fetch(url);
19
+ if (!response.ok) {
20
+ throw new Error(`Failed to fetch UTXOs: ${await response.text()}`);
21
+ }
22
+ return await response.json();
23
+ }
24
+ };
25
+ //# sourceMappingURL=BitcoinApi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_appkitCommonReactNative","require","BitcoinApi","exports","getUTXOs","network","address","isTestnet","caipNetworkId","bitcoinTestnet","url","response","fetch","ok","Error","text","json"],"sourceRoot":"../../../src","sources":["utils/BitcoinApi.ts"],"mappings":";;;;;;AAAA,IAAAA,wBAAA,GAAAC,OAAA;AAEO,MAAMC,UAAgC,GAAAC,OAAA,CAAAD,UAAA,GAAG;EAC9CE,QAAQ,EAAE,MAAAA,CAAO;IAAEC,OAAO;IAAEC;EAAmC,CAAC,KAAiC;IAC/F,MAAMC,SAAS,GAAGF,OAAO,CAACG,aAAa,KAAKC,uCAAc,CAACD,aAAa;IACxE;;IAEA;IACA,MAAME,GAAG,GAAG,wBAAwBH,SAAS,GAAG,UAAU,GAAG,EAAE,gBAAgBD,OAAO,OAAO;IAC7F,MAAMK,QAAQ,GAAG,MAAMC,KAAK,CAACF,GAAG,CAAC;IAEjC,IAAI,CAACC,QAAQ,CAACE,EAAE,EAAE;MAChB,MAAM,IAAIC,KAAK,CAAC,0BAA0B,MAAMH,QAAQ,CAACI,IAAI,CAAC,CAAC,EAAE,CAAC;IACpE;IAEA,OAAQ,MAAMJ,QAAQ,CAACK,IAAI,CAAC,CAAC;EAC/B;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FormatUtil = void 0;
7
+ const FormatUtil = exports.FormatUtil = {
8
+ normalizeSignature(signature) {
9
+ let raw;
10
+ try {
11
+ // Try hex first
12
+ raw = Buffer.from(signature, 'hex');
13
+ if (raw.length > 0 && /^[0-9a-fA-F]+$/.test(signature)) {
14
+ return {
15
+ hex: signature,
16
+ base64: raw.toString('base64')
17
+ };
18
+ }
19
+ } catch {
20
+ // ignore and try base64
21
+ }
22
+ try {
23
+ // Fallback: assume base64
24
+ raw = Buffer.from(signature, 'base64');
25
+ if (raw.length > 0) {
26
+ return {
27
+ hex: raw.toString('hex'),
28
+ base64: signature
29
+ };
30
+ }
31
+ } catch {
32
+ // ignore
33
+ }
34
+ throw new Error('Unsupported signature format: expected hex or base64');
35
+ }
36
+ };
37
+ //# sourceMappingURL=FormatUtil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["FormatUtil","exports","normalizeSignature","signature","raw","Buffer","from","length","test","hex","base64","toString","Error"],"sourceRoot":"../../../src","sources":["utils/FormatUtil.ts"],"mappings":";;;;;;AAAO,MAAMA,UAAU,GAAAC,OAAA,CAAAD,UAAA,GAAG;EACxBE,kBAAkBA,CAACC,SAAiB,EAAmC;IACrE,IAAIC,GAAW;IAEf,IAAI;MACF;MACAA,GAAG,GAAGC,MAAM,CAACC,IAAI,CAACH,SAAS,EAAE,KAAK,CAAC;MACnC,IAAIC,GAAG,CAACG,MAAM,GAAG,CAAC,IAAI,gBAAgB,CAACC,IAAI,CAACL,SAAS,CAAC,EAAE;QACtD,OAAO;UACLM,GAAG,EAAEN,SAAS;UACdO,MAAM,EAAEN,GAAG,CAACO,QAAQ,CAAC,QAAQ;QAC/B,CAAC;MACH;IACF,CAAC,CAAC,MAAM;MACN;IAAA;IAGF,IAAI;MACF;MACAP,GAAG,GAAGC,MAAM,CAACC,IAAI,CAACH,SAAS,EAAE,QAAQ,CAAC;MACtC,IAAIC,GAAG,CAACG,MAAM,GAAG,CAAC,EAAE;QAClB,OAAO;UACLE,GAAG,EAAEL,GAAG,CAACO,QAAQ,CAAC,KAAK,CAAC;UACxBD,MAAM,EAAEP;QACV,CAAC;MACH;IACF,CAAC,CAAC,MAAM;MACN;IAAA;IAGF,MAAM,IAAIS,KAAK,CAAC,sDAAsD,CAAC;EACzE;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.UnitsUtil = void 0;
7
+ const UnitsUtil = exports.UnitsUtil = {
8
+ parseSatoshis(amount, network) {
9
+ const value = parseFloat(amount) / 10 ** network.nativeCurrency.decimals;
10
+ return Intl.NumberFormat('en-US', {
11
+ maximumFractionDigits: network.nativeCurrency.decimals
12
+ }).format(value);
13
+ }
14
+ };
15
+ //# sourceMappingURL=UnitsUtil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["UnitsUtil","exports","parseSatoshis","amount","network","value","parseFloat","nativeCurrency","decimals","Intl","NumberFormat","maximumFractionDigits","format"],"sourceRoot":"../../../src","sources":["utils/UnitsUtil.ts"],"mappings":";;;;;;AAEO,MAAMA,SAAS,GAAAC,OAAA,CAAAD,SAAA,GAAG;EACvBE,aAAaA,CAACC,MAAc,EAAEC,OAAsB,EAAU;IAC5D,MAAMC,KAAK,GAAGC,UAAU,CAACH,MAAM,CAAC,GAAG,EAAE,IAAIC,OAAO,CAACG,cAAc,CAACC,QAAQ;IAExE,OAAOC,IAAI,CAACC,YAAY,CAAC,OAAO,EAAE;MAChCC,qBAAqB,EAAEP,OAAO,CAACG,cAAc,CAACC;IAChD,CAAC,CAAC,CAACI,MAAM,CAACP,KAAK,CAAC;EAClB;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+
3
+ import { BitcoinBaseAdapter } from '@reown/appkit-common-react-native';
4
+ import { BitcoinApi } from './utils/BitcoinApi';
5
+ import { UnitsUtil } from './utils/UnitsUtil';
6
+ import { FormatUtil } from './utils/FormatUtil';
7
+ export class BitcoinAdapter extends BitcoinBaseAdapter {
8
+ static supportedNamespace = 'bip122';
9
+ static api = BitcoinApi;
10
+ constructor() {
11
+ super({
12
+ supportedNamespace: BitcoinAdapter.supportedNamespace,
13
+ adapterType: 'bip122'
14
+ });
15
+ }
16
+ async getBalance(params) {
17
+ const {
18
+ network,
19
+ address
20
+ } = params;
21
+ if (!this.connector) throw new Error('No active connector');
22
+ if (!network) throw new Error('No network provided');
23
+ const balanceCaipAddress = address || this.getAccounts()?.find(account => account.includes(network.id.toString()));
24
+ const balanceAddress = balanceCaipAddress?.split(':')[2];
25
+ if (!balanceCaipAddress || !balanceAddress) {
26
+ return Promise.resolve({
27
+ amount: '0.00',
28
+ symbol: 'BTC'
29
+ });
30
+ }
31
+ try {
32
+ const utxos = await BitcoinAdapter.api.getUTXOs({
33
+ network,
34
+ address: balanceAddress
35
+ });
36
+ const balance = utxos.reduce((acc, utxo) => acc + utxo.value, 0);
37
+ const formattedBalance = UnitsUtil.parseSatoshis(balance.toString(), network);
38
+ this.emit('balanceChanged', {
39
+ address: balanceCaipAddress,
40
+ balance: {
41
+ amount: formattedBalance,
42
+ symbol: network.nativeCurrency.symbol
43
+ }
44
+ });
45
+ return {
46
+ amount: formattedBalance,
47
+ symbol: network.nativeCurrency.symbol
48
+ };
49
+ } catch (error) {
50
+ return {
51
+ amount: '0.00',
52
+ symbol: 'BTC'
53
+ };
54
+ }
55
+ }
56
+ async switchNetwork(network) {
57
+ if (!this.connector) throw new Error('No active connector');
58
+ const provider = this.connector.getProvider('bip122');
59
+ if (!provider) throw new Error('No active provider');
60
+ try {
61
+ await this.connector.switchNetwork(network);
62
+ return;
63
+ } catch (switchError) {
64
+ throw switchError;
65
+ }
66
+ }
67
+ getAccounts() {
68
+ if (!this.connector) throw new Error('No active connector');
69
+ const namespaces = this.connector.getNamespaces();
70
+ return namespaces[this.getSupportedNamespace()]?.accounts;
71
+ }
72
+ disconnect() {
73
+ if (!this.connector) throw new Error('SolanaAdapter:disconnect - No active connector');
74
+ return this.connector.disconnect();
75
+ }
76
+ getSupportedNamespace() {
77
+ return BitcoinAdapter.supportedNamespace;
78
+ }
79
+ async signMessage(address, message, chainId) {
80
+ if (!this.connector) throw new Error('BitcoinAdapter:signMessage - No active connector');
81
+ const provider = this.connector.getProvider('bip122');
82
+ if (!provider) throw new Error('BitcoinAdapter:signMessage - No active provider');
83
+ const chain = chainId ? `${this.getSupportedNamespace()}:${chainId}` : undefined;
84
+ const {
85
+ signature
86
+ } = await provider.request({
87
+ method: 'signMessage',
88
+ params: {
89
+ message,
90
+ account: address,
91
+ address,
92
+ protocol: 'ecdsa'
93
+ }
94
+ }, chain);
95
+ const formattedSignature = FormatUtil.normalizeSignature(signature);
96
+ return formattedSignature.base64;
97
+ }
98
+ }
99
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["BitcoinBaseAdapter","BitcoinApi","UnitsUtil","FormatUtil","BitcoinAdapter","supportedNamespace","api","constructor","adapterType","getBalance","params","network","address","connector","Error","balanceCaipAddress","getAccounts","find","account","includes","id","toString","balanceAddress","split","Promise","resolve","amount","symbol","utxos","getUTXOs","balance","reduce","acc","utxo","value","formattedBalance","parseSatoshis","emit","nativeCurrency","error","switchNetwork","provider","getProvider","switchError","namespaces","getNamespaces","getSupportedNamespace","accounts","disconnect","signMessage","message","chainId","chain","undefined","signature","request","method","protocol","formattedSignature","normalizeSignature","base64"],"sourceRoot":"../../src","sources":["adapter.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ import { BitcoinAdapter } from './adapter';
4
+ export { BitcoinAdapter };
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["BitcoinAdapter"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,cAAc,QAAQ,WAAW;AAC1C,SAASA,cAAc","ignoreList":[]}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ import { bitcoinTestnet } from '@reown/appkit-common-react-native';
4
+ export const BitcoinApi = {
5
+ getUTXOs: async ({
6
+ network,
7
+ address
8
+ }) => {
9
+ const isTestnet = network.caipNetworkId === bitcoinTestnet.caipNetworkId;
10
+ // Make chain dynamic
11
+
12
+ //TODO: Call rpc to get balance
13
+ const url = `https://mempool.space${isTestnet ? '/testnet' : ''}/api/address/${address}/utxo`;
14
+ const response = await fetch(url);
15
+ if (!response.ok) {
16
+ throw new Error(`Failed to fetch UTXOs: ${await response.text()}`);
17
+ }
18
+ return await response.json();
19
+ }
20
+ };
21
+ //# sourceMappingURL=BitcoinApi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["bitcoinTestnet","BitcoinApi","getUTXOs","network","address","isTestnet","caipNetworkId","url","response","fetch","ok","Error","text","json"],"sourceRoot":"../../../src","sources":["utils/BitcoinApi.ts"],"mappings":";;AAAA,SAA6BA,cAAc,QAAQ,mCAAmC;AAEtF,OAAO,MAAMC,UAAgC,GAAG;EAC9CC,QAAQ,EAAE,MAAAA,CAAO;IAAEC,OAAO;IAAEC;EAAmC,CAAC,KAAiC;IAC/F,MAAMC,SAAS,GAAGF,OAAO,CAACG,aAAa,KAAKN,cAAc,CAACM,aAAa;IACxE;;IAEA;IACA,MAAMC,GAAG,GAAG,wBAAwBF,SAAS,GAAG,UAAU,GAAG,EAAE,gBAAgBD,OAAO,OAAO;IAC7F,MAAMI,QAAQ,GAAG,MAAMC,KAAK,CAACF,GAAG,CAAC;IAEjC,IAAI,CAACC,QAAQ,CAACE,EAAE,EAAE;MAChB,MAAM,IAAIC,KAAK,CAAC,0BAA0B,MAAMH,QAAQ,CAACI,IAAI,CAAC,CAAC,EAAE,CAAC;IACpE;IAEA,OAAQ,MAAMJ,QAAQ,CAACK,IAAI,CAAC,CAAC;EAC/B;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ export const FormatUtil = {
4
+ normalizeSignature(signature) {
5
+ let raw;
6
+ try {
7
+ // Try hex first
8
+ raw = Buffer.from(signature, 'hex');
9
+ if (raw.length > 0 && /^[0-9a-fA-F]+$/.test(signature)) {
10
+ return {
11
+ hex: signature,
12
+ base64: raw.toString('base64')
13
+ };
14
+ }
15
+ } catch {
16
+ // ignore and try base64
17
+ }
18
+ try {
19
+ // Fallback: assume base64
20
+ raw = Buffer.from(signature, 'base64');
21
+ if (raw.length > 0) {
22
+ return {
23
+ hex: raw.toString('hex'),
24
+ base64: signature
25
+ };
26
+ }
27
+ } catch {
28
+ // ignore
29
+ }
30
+ throw new Error('Unsupported signature format: expected hex or base64');
31
+ }
32
+ };
33
+ //# sourceMappingURL=FormatUtil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["FormatUtil","normalizeSignature","signature","raw","Buffer","from","length","test","hex","base64","toString","Error"],"sourceRoot":"../../../src","sources":["utils/FormatUtil.ts"],"mappings":";;AAAA,OAAO,MAAMA,UAAU,GAAG;EACxBC,kBAAkBA,CAACC,SAAiB,EAAmC;IACrE,IAAIC,GAAW;IAEf,IAAI;MACF;MACAA,GAAG,GAAGC,MAAM,CAACC,IAAI,CAACH,SAAS,EAAE,KAAK,CAAC;MACnC,IAAIC,GAAG,CAACG,MAAM,GAAG,CAAC,IAAI,gBAAgB,CAACC,IAAI,CAACL,SAAS,CAAC,EAAE;QACtD,OAAO;UACLM,GAAG,EAAEN,SAAS;UACdO,MAAM,EAAEN,GAAG,CAACO,QAAQ,CAAC,QAAQ;QAC/B,CAAC;MACH;IACF,CAAC,CAAC,MAAM;MACN;IAAA;IAGF,IAAI;MACF;MACAP,GAAG,GAAGC,MAAM,CAACC,IAAI,CAACH,SAAS,EAAE,QAAQ,CAAC;MACtC,IAAIC,GAAG,CAACG,MAAM,GAAG,CAAC,EAAE;QAClB,OAAO;UACLE,GAAG,EAAEL,GAAG,CAACO,QAAQ,CAAC,KAAK,CAAC;UACxBD,MAAM,EAAEP;QACV,CAAC;MACH;IACF,CAAC,CAAC,MAAM;MACN;IAAA;IAGF,MAAM,IAAIS,KAAK,CAAC,sDAAsD,CAAC;EACzE;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ export const UnitsUtil = {
4
+ parseSatoshis(amount, network) {
5
+ const value = parseFloat(amount) / 10 ** network.nativeCurrency.decimals;
6
+ return Intl.NumberFormat('en-US', {
7
+ maximumFractionDigits: network.nativeCurrency.decimals
8
+ }).format(value);
9
+ }
10
+ };
11
+ //# sourceMappingURL=UnitsUtil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["UnitsUtil","parseSatoshis","amount","network","value","parseFloat","nativeCurrency","decimals","Intl","NumberFormat","maximumFractionDigits","format"],"sourceRoot":"../../../src","sources":["utils/UnitsUtil.ts"],"mappings":";;AAEA,OAAO,MAAMA,SAAS,GAAG;EACvBC,aAAaA,CAACC,MAAc,EAAEC,OAAsB,EAAU;IAC5D,MAAMC,KAAK,GAAGC,UAAU,CAACH,MAAM,CAAC,GAAG,EAAE,IAAIC,OAAO,CAACG,cAAc,CAACC,QAAQ;IAExE,OAAOC,IAAI,CAACC,YAAY,CAAC,OAAO,EAAE;MAChCC,qBAAqB,EAAEP,OAAO,CAACG,cAAc,CAACC;IAChD,CAAC,CAAC,CAACI,MAAM,CAACP,KAAK,CAAC;EAClB;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,13 @@
1
+ import { BitcoinBaseAdapter, type AppKitNetwork, type CaipAddress, type ChainNamespace, type GetBalanceParams, type GetBalanceResponse } from '@reown/appkit-common-react-native';
2
+ export declare class BitcoinAdapter extends BitcoinBaseAdapter {
3
+ private static supportedNamespace;
4
+ private static api;
5
+ constructor();
6
+ getBalance(params: GetBalanceParams): Promise<GetBalanceResponse>;
7
+ switchNetwork(network: AppKitNetwork): Promise<void>;
8
+ getAccounts(): CaipAddress[] | undefined;
9
+ disconnect(): Promise<void>;
10
+ getSupportedNamespace(): ChainNamespace;
11
+ signMessage(address: string, message: string, chainId?: string): Promise<string>;
12
+ }
13
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACxB,MAAM,mCAAmC,CAAC;AAK3C,qBAAa,cAAe,SAAQ,kBAAkB;IACpD,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAA4B;IAC7D,OAAO,CAAC,MAAM,CAAC,GAAG,CAAc;;IAS1B,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAsCjE,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D,WAAW,IAAI,WAAW,EAAE,GAAG,SAAS;IAOxC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,qBAAqB,IAAI,cAAc;IAIjC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAoBvF"}
@@ -0,0 +1,3 @@
1
+ import { BitcoinAdapter } from './adapter';
2
+ export { BitcoinAdapter };
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { type AppKitNetwork } from '@reown/appkit-common-react-native';
2
+ export declare const BitcoinApi: BitcoinApi.Interface;
3
+ export declare namespace BitcoinApi {
4
+ type Interface = {
5
+ getUTXOs: (params: GetUTXOsParams) => Promise<UTXO[]>;
6
+ };
7
+ type GetUTXOsParams = {
8
+ network: AppKitNetwork;
9
+ address: string;
10
+ };
11
+ type UTXO = {
12
+ txid: string;
13
+ vout: number;
14
+ value: number;
15
+ status: {
16
+ confirmed: boolean;
17
+ block_height: number;
18
+ block_hash: string;
19
+ block_time: number;
20
+ };
21
+ };
22
+ }
23
+ //# sourceMappingURL=BitcoinApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BitcoinApi.d.ts","sourceRoot":"","sources":["../../../src/utils/BitcoinApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,mCAAmC,CAAC;AAEvF,eAAO,MAAM,UAAU,EAAE,UAAU,CAAC,SAenC,CAAC;AAEF,yBAAiB,UAAU,CAAC;IAC1B,KAAY,SAAS,GAAG;QACtB,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;KACvD,CAAC;IAEF,KAAY,cAAc,GAAG;QAC3B,OAAO,EAAE,aAAa,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF,KAAY,IAAI,GAAG;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE;YACN,SAAS,EAAE,OAAO,CAAC;YACnB,YAAY,EAAE,MAAM,CAAC;YACrB,UAAU,EAAE,MAAM,CAAC;YACnB,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;KACH,CAAC;CACH"}
@@ -0,0 +1,7 @@
1
+ export declare const FormatUtil: {
2
+ normalizeSignature(signature: string): {
3
+ hex: string;
4
+ base64: string;
5
+ };
6
+ };
7
+ //# sourceMappingURL=FormatUtil.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormatUtil.d.ts","sourceRoot":"","sources":["../../../src/utils/FormatUtil.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;kCACS,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CA+BvE,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { AppKitNetwork } from '@reown/appkit-common-react-native';
2
+ export declare const UnitsUtil: {
3
+ parseSatoshis(amount: string, network: AppKitNetwork): string;
4
+ };
5
+ //# sourceMappingURL=UnitsUtil.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UnitsUtil.d.ts","sourceRoot":"","sources":["../../../src/utils/UnitsUtil.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAEvE,eAAO,MAAM,SAAS;0BACE,MAAM,WAAW,aAAa,GAAG,MAAM;CAO9D,CAAC"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@reown/appkit-bitcoin-react-native",
3
+ "version": "0.0.0-canary-20251008180350",
4
+ "main": "lib/commonjs/index.js",
5
+ "types": "lib/typescript/index.d.ts",
6
+ "module": "lib/module/index.js",
7
+ "react-native": "src/index.tsx",
8
+ "source": "src/index.tsx",
9
+ "scripts": {
10
+ "build": "bob build",
11
+ "clean": "rm -rf lib",
12
+ "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
13
+ },
14
+ "files": [
15
+ "src",
16
+ "lib",
17
+ "!**/__tests__",
18
+ "!**/__fixtures__",
19
+ "!**/__mocks__"
20
+ ],
21
+ "keywords": [
22
+ "web3",
23
+ "crypto",
24
+ "bitcoin",
25
+ "appkit",
26
+ "reown",
27
+ "walletconnect",
28
+ "react-native"
29
+ ],
30
+ "repository": "https://github.com/reown-com/appkit-react-native",
31
+ "author": "Reown (https://discord.gg/reown)",
32
+ "homepage": "https://reown.com/appkit",
33
+ "license": "SEE LICENSE IN LICENSE.md",
34
+ "bugs": {
35
+ "url": "https://github.com/reown-com/appkit-react-native/issues"
36
+ },
37
+ "publishConfig": {
38
+ "registry": "https://registry.npmjs.org/",
39
+ "access": "public",
40
+ "provenance": true
41
+ },
42
+ "dependencies": {
43
+ "@reown/appkit-common-react-native": "0.0.0-canary-20251008180350"
44
+ },
45
+ "peerDependencies": {
46
+ "@walletconnect/react-native-compat": ">=2.16.1",
47
+ "react": ">=18",
48
+ "react-native": ">=0.72"
49
+ }
50
+ }
package/readme.md ADDED
@@ -0,0 +1,9 @@
1
+ #### 📚 [Documentation](https://docs.reown.com/appkit/react-native/core/installation)
2
+
3
+ #### 🔎 [Examples](https://github.com/reown-com/react-native-examples)
4
+
5
+ #### 🔗 [Website](https://reown.com/appkit)
6
+
7
+ # AppKit
8
+
9
+ Your on-ramp to web3 multichain. AppKit is a versatile library that makes it super easy to connect users with your Dapp and start interacting with the blockchain.
package/src/adapter.ts ADDED
@@ -0,0 +1,114 @@
1
+ import {
2
+ BitcoinBaseAdapter,
3
+ type AppKitNetwork,
4
+ type CaipAddress,
5
+ type ChainNamespace,
6
+ type GetBalanceParams,
7
+ type GetBalanceResponse
8
+ } from '@reown/appkit-common-react-native';
9
+ import { BitcoinApi } from './utils/BitcoinApi';
10
+ import { UnitsUtil } from './utils/UnitsUtil';
11
+ import { FormatUtil } from './utils/FormatUtil';
12
+
13
+ export class BitcoinAdapter extends BitcoinBaseAdapter {
14
+ private static supportedNamespace: ChainNamespace = 'bip122';
15
+ private static api = BitcoinApi;
16
+
17
+ constructor() {
18
+ super({
19
+ supportedNamespace: BitcoinAdapter.supportedNamespace,
20
+ adapterType: 'bip122'
21
+ });
22
+ }
23
+
24
+ async getBalance(params: GetBalanceParams): Promise<GetBalanceResponse> {
25
+ const { network, address } = params;
26
+
27
+ if (!this.connector) throw new Error('No active connector');
28
+ if (!network) throw new Error('No network provided');
29
+
30
+ const balanceCaipAddress =
31
+ address || this.getAccounts()?.find(account => account.includes(network.id.toString()));
32
+
33
+ const balanceAddress = balanceCaipAddress?.split(':')[2];
34
+
35
+ if (!balanceCaipAddress || !balanceAddress) {
36
+ return Promise.resolve({ amount: '0.00', symbol: 'BTC' });
37
+ }
38
+
39
+ try {
40
+ const utxos = await BitcoinAdapter.api.getUTXOs({
41
+ network,
42
+ address: balanceAddress
43
+ });
44
+
45
+ const balance = utxos.reduce((acc, utxo) => acc + utxo.value, 0);
46
+ const formattedBalance = UnitsUtil.parseSatoshis(balance.toString(), network);
47
+
48
+ this.emit('balanceChanged', {
49
+ address: balanceCaipAddress,
50
+ balance: {
51
+ amount: formattedBalance,
52
+ symbol: network.nativeCurrency.symbol
53
+ }
54
+ });
55
+
56
+ return { amount: formattedBalance, symbol: network.nativeCurrency.symbol };
57
+ } catch (error) {
58
+ return { amount: '0.00', symbol: 'BTC' };
59
+ }
60
+ }
61
+
62
+ async switchNetwork(network: AppKitNetwork): Promise<void> {
63
+ if (!this.connector) throw new Error('No active connector');
64
+
65
+ const provider = this.connector.getProvider('bip122');
66
+ if (!provider) throw new Error('No active provider');
67
+
68
+ try {
69
+ await this.connector.switchNetwork(network);
70
+
71
+ return;
72
+ } catch (switchError: any) {
73
+ throw switchError;
74
+ }
75
+ }
76
+
77
+ getAccounts(): CaipAddress[] | undefined {
78
+ if (!this.connector) throw new Error('No active connector');
79
+ const namespaces = this.connector.getNamespaces();
80
+
81
+ return namespaces[this.getSupportedNamespace()]?.accounts;
82
+ }
83
+
84
+ disconnect(): Promise<void> {
85
+ if (!this.connector) throw new Error('SolanaAdapter:disconnect - No active connector');
86
+
87
+ return this.connector.disconnect();
88
+ }
89
+
90
+ getSupportedNamespace(): ChainNamespace {
91
+ return BitcoinAdapter.supportedNamespace;
92
+ }
93
+
94
+ async signMessage(address: string, message: string, chainId?: string): Promise<string> {
95
+ if (!this.connector) throw new Error('BitcoinAdapter:signMessage - No active connector');
96
+
97
+ const provider = this.connector.getProvider('bip122');
98
+ if (!provider) throw new Error('BitcoinAdapter:signMessage - No active provider');
99
+
100
+ const chain = chainId ? `${this.getSupportedNamespace()}:${chainId}` : undefined;
101
+
102
+ const { signature } = (await provider.request(
103
+ {
104
+ method: 'signMessage',
105
+ params: { message, account: address, address, protocol: 'ecdsa' }
106
+ },
107
+ chain
108
+ )) as { address: string; signature: string };
109
+
110
+ const formattedSignature = FormatUtil.normalizeSignature(signature);
111
+
112
+ return formattedSignature.base64;
113
+ }
114
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,2 @@
1
+ import { BitcoinAdapter } from './adapter';
2
+ export { BitcoinAdapter };
@@ -0,0 +1,41 @@
1
+ import { type AppKitNetwork, bitcoinTestnet } from '@reown/appkit-common-react-native';
2
+
3
+ export const BitcoinApi: BitcoinApi.Interface = {
4
+ getUTXOs: async ({ network, address }: BitcoinApi.GetUTXOsParams): Promise<BitcoinApi.UTXO[]> => {
5
+ const isTestnet = network.caipNetworkId === bitcoinTestnet.caipNetworkId;
6
+ // Make chain dynamic
7
+
8
+ //TODO: Call rpc to get balance
9
+ const url = `https://mempool.space${isTestnet ? '/testnet' : ''}/api/address/${address}/utxo`;
10
+ const response = await fetch(url);
11
+
12
+ if (!response.ok) {
13
+ throw new Error(`Failed to fetch UTXOs: ${await response.text()}`);
14
+ }
15
+
16
+ return (await response.json()) as BitcoinApi.UTXO[];
17
+ }
18
+ };
19
+
20
+ export namespace BitcoinApi {
21
+ export type Interface = {
22
+ getUTXOs: (params: GetUTXOsParams) => Promise<UTXO[]>;
23
+ };
24
+
25
+ export type GetUTXOsParams = {
26
+ network: AppKitNetwork;
27
+ address: string;
28
+ };
29
+
30
+ export type UTXO = {
31
+ txid: string;
32
+ vout: number;
33
+ value: number;
34
+ status: {
35
+ confirmed: boolean;
36
+ block_height: number;
37
+ block_hash: string;
38
+ block_time: number;
39
+ };
40
+ };
41
+ }
@@ -0,0 +1,33 @@
1
+ export const FormatUtil = {
2
+ normalizeSignature(signature: string): { hex: string; base64: string } {
3
+ let raw: Buffer;
4
+
5
+ try {
6
+ // Try hex first
7
+ raw = Buffer.from(signature, 'hex');
8
+ if (raw.length > 0 && /^[0-9a-fA-F]+$/.test(signature)) {
9
+ return {
10
+ hex: signature,
11
+ base64: raw.toString('base64')
12
+ };
13
+ }
14
+ } catch {
15
+ // ignore and try base64
16
+ }
17
+
18
+ try {
19
+ // Fallback: assume base64
20
+ raw = Buffer.from(signature, 'base64');
21
+ if (raw.length > 0) {
22
+ return {
23
+ hex: raw.toString('hex'),
24
+ base64: signature
25
+ };
26
+ }
27
+ } catch {
28
+ // ignore
29
+ }
30
+
31
+ throw new Error('Unsupported signature format: expected hex or base64');
32
+ }
33
+ };
@@ -0,0 +1,11 @@
1
+ import type { AppKitNetwork } from '@reown/appkit-common-react-native';
2
+
3
+ export const UnitsUtil = {
4
+ parseSatoshis(amount: string, network: AppKitNetwork): string {
5
+ const value = parseFloat(amount) / 10 ** network.nativeCurrency.decimals;
6
+
7
+ return Intl.NumberFormat('en-US', {
8
+ maximumFractionDigits: network.nativeCurrency.decimals
9
+ }).format(value);
10
+ }
11
+ };