@utxopia/sdk 0.1.0-alpha.2 → 0.1.0-alpha.3
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.
- package/README.md +214 -108
- package/{packages/sdk/dist → dist}/client.d.ts +25 -1
- package/{packages/sdk/dist → dist}/client.js +36 -1
- package/{packages/sdk/dist → dist}/crypto-ed25519.d.ts +14 -0
- package/{packages/sdk/dist → dist}/crypto-ed25519.js +14 -0
- package/{packages/sdk/dist → dist}/index.d.ts +3 -3
- package/{packages/sdk/dist → dist}/index.js +3 -3
- package/{packages/sdk/dist → dist}/instructions.d.ts +28 -11
- package/{packages/sdk/dist → dist}/instructions.js +45 -15
- package/{packages/sdk/dist → dist}/stealth.d.ts +104 -9
- package/{packages/sdk/dist → dist}/stealth.js +146 -14
- package/{packages/sdk/dist → dist}/taproot.d.ts +39 -2
- package/{packages/sdk/dist → dist}/taproot.js +54 -2
- package/package.json +86 -63
- package/src/announcement-client.ts +457 -0
- package/src/auditor-ciphertext.ts +181 -0
- package/src/auditor.ts +409 -0
- package/src/bitcoin/ika.ts +103 -0
- package/src/bitcoin/index.ts +5 -0
- package/src/bound-params.ts +322 -0
- package/src/chadbuffer.ts +603 -0
- package/src/circomlibjs.d.ts +51 -0
- package/src/claim-link.ts +53 -0
- package/src/client.ts +638 -0
- package/src/commitment-tree.ts +736 -0
- package/src/config.ts +772 -0
- package/src/core/esplora.ts +332 -0
- package/src/core/mempool.ts +159 -0
- package/src/crypto-babyjub.ts +385 -0
- package/src/crypto-ed25519.ts +297 -0
- package/src/crypto.ts +199 -0
- package/src/event-client.ts +231 -0
- package/src/events.ts +384 -0
- package/src/explorer.ts +300 -0
- package/src/index.ts +902 -0
- package/src/instructions.ts +2820 -0
- package/src/keys.ts +1228 -0
- package/src/logger.ts +41 -0
- package/src/magicblock.ts +278 -0
- package/src/merkle.ts +197 -0
- package/src/note.ts +754 -0
- package/src/pda.ts +516 -0
- package/src/pool-state.ts +176 -0
- package/src/poseidon.ts +175 -0
- package/src/prover/index.ts +19 -0
- package/src/prover/mobile.ts +303 -0
- package/src/prover/web.ts +771 -0
- package/src/psbt.ts +333 -0
- package/src/selective-disclosure.ts +284 -0
- package/src/sender-memo.ts +343 -0
- package/src/snarkjs.d.ts +19 -0
- package/src/sns-resolver.ts +333 -0
- package/src/solana/connection.ts +189 -0
- package/src/solana/priority-fee.ts +201 -0
- package/src/spend-doc.ts +163 -0
- package/src/stealth.ts +1477 -0
- package/src/taproot.ts +707 -0
- package/src/token-registry.ts +207 -0
- package/src/utils/encoding.ts +33 -0
- package/src/vk-registry.ts +295 -0
- package/LICENSE +0 -21
- package/packages/btc-client/src/esplora-client.ts +0 -153
- package/packages/btc-client/src/index.ts +0 -3
- package/packages/btc-client/src/op-return.ts +0 -93
- package/packages/btc-client/src/types.ts +0 -112
- package/packages/sdk/README.md +0 -277
- /package/{packages/sdk/dist → dist}/announcement-client.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/announcement-client.js +0 -0
- /package/{packages/sdk/dist → dist}/auditor-ciphertext.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/auditor-ciphertext.js +0 -0
- /package/{packages/sdk/dist → dist}/auditor.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/auditor.js +0 -0
- /package/{packages/sdk/dist → dist}/bitcoin/ika.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/bitcoin/ika.js +0 -0
- /package/{packages/sdk/dist → dist}/bitcoin/index.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/bitcoin/index.js +0 -0
- /package/{packages/sdk/dist → dist}/bound-params.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/bound-params.js +0 -0
- /package/{packages/sdk/dist → dist}/chadbuffer.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/chadbuffer.js +0 -0
- /package/{packages/sdk/dist → dist}/claim-link.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/claim-link.js +0 -0
- /package/{packages/sdk/dist → dist}/commitment-tree.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/commitment-tree.js +0 -0
- /package/{packages/sdk/dist → dist}/config.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/config.js +0 -0
- /package/{packages/sdk/dist → dist}/core/esplora.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/core/esplora.js +0 -0
- /package/{packages/sdk/dist → dist}/core/mempool.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/core/mempool.js +0 -0
- /package/{packages/sdk/dist → dist}/crypto-babyjub.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/crypto-babyjub.js +0 -0
- /package/{packages/sdk/dist → dist}/crypto.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/crypto.js +0 -0
- /package/{packages/sdk/dist → dist}/event-client.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/event-client.js +0 -0
- /package/{packages/sdk/dist → dist}/events.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/events.js +0 -0
- /package/{packages/sdk/dist → dist}/explorer.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/explorer.js +0 -0
- /package/{packages/sdk/dist → dist}/keys.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/keys.js +0 -0
- /package/{packages/sdk/dist → dist}/logger.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/logger.js +0 -0
- /package/{packages/sdk/dist → dist}/magicblock.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/magicblock.js +0 -0
- /package/{packages/sdk/dist → dist}/merkle.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/merkle.js +0 -0
- /package/{packages/sdk/dist → dist}/note.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/note.js +0 -0
- /package/{packages/sdk/dist → dist}/pda.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/pda.js +0 -0
- /package/{packages/sdk/dist → dist}/pool-state.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/pool-state.js +0 -0
- /package/{packages/sdk/dist → dist}/poseidon.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/poseidon.js +0 -0
- /package/{packages/sdk/dist → dist}/prover/index.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/prover/index.js +0 -0
- /package/{packages/sdk/dist → dist}/prover/mobile.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/prover/mobile.js +0 -0
- /package/{packages/sdk/dist → dist}/prover/web.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/prover/web.js +0 -0
- /package/{packages/sdk/dist → dist}/psbt.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/psbt.js +0 -0
- /package/{packages/sdk/dist → dist}/selective-disclosure.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/selective-disclosure.js +0 -0
- /package/{packages/sdk/dist → dist}/sender-memo.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/sender-memo.js +0 -0
- /package/{packages/sdk/dist → dist}/sns-resolver.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/sns-resolver.js +0 -0
- /package/{packages/sdk/dist → dist}/solana/connection.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/solana/connection.js +0 -0
- /package/{packages/sdk/dist → dist}/solana/priority-fee.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/solana/priority-fee.js +0 -0
- /package/{packages/sdk/dist → dist}/spend-doc.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/spend-doc.js +0 -0
- /package/{packages/sdk/dist → dist}/token-registry.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/token-registry.js +0 -0
- /package/{packages/sdk/dist → dist}/utils/encoding.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/utils/encoding.js +0 -0
- /package/{packages/sdk/dist → dist}/vk-registry.d.ts +0 -0
- /package/{packages/sdk/dist → dist}/vk-registry.js +0 -0
|
@@ -68,17 +68,18 @@ export function deriveTaprootAddress(commitment, network = "testnet", internalKe
|
|
|
68
68
|
address,
|
|
69
69
|
outputKey,
|
|
70
70
|
tweak,
|
|
71
|
+
parity: outputKeyHex.startsWith("03") ? 1 : 0,
|
|
71
72
|
};
|
|
72
73
|
}
|
|
73
74
|
/**
|
|
74
|
-
*
|
|
75
|
+
* Per-deposit commitment carried in a `verify_deposit` (disc 25) address's tapleaf.
|
|
75
76
|
*
|
|
76
77
|
* Both keys are hashed in. Binding the note key alone would leave the ephemeral
|
|
77
78
|
* pubkey caller-chosen on the Solana side: the credited amount and owner would
|
|
78
79
|
* still be right, but a substituted ephemeral key makes the stealth announcement
|
|
79
80
|
* undecryptable and the recipient never finds their note.
|
|
80
81
|
*
|
|
81
|
-
* Feed the result to `
|
|
82
|
+
* Feed the result to `deriveDepositAddress`.
|
|
82
83
|
*/
|
|
83
84
|
export function depositTweakCommitment(notePublicKey, ephemeralPubkey) {
|
|
84
85
|
if (notePublicKey.length !== 32 || ephemeralPubkey.length !== 32) {
|
|
@@ -89,6 +90,57 @@ export function depositTweakCommitment(notePublicKey, ephemeralPubkey) {
|
|
|
89
90
|
material.set(ephemeralPubkey, 32);
|
|
90
91
|
return sha256(material);
|
|
91
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* BIP-341's suggested NUMS point, used as the deposit address's internal key.
|
|
95
|
+
*
|
|
96
|
+
* Nobody knows its discrete log, so the key path is unspendable and custody
|
|
97
|
+
* rests entirely on the script path. That is deliberate: Ika's MPC cannot sign
|
|
98
|
+
* for a tweaked key, so an address whose internal key were the dWallet key plus
|
|
99
|
+
* a per-deposit tweak would be unspendable by the custodian meant to sweep it.
|
|
100
|
+
*/
|
|
101
|
+
export const DEPOSIT_NUMS_INTERNAL_KEY = hexToBytes("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0");
|
|
102
|
+
/**
|
|
103
|
+
* The single tapleaf a deposit address commits to:
|
|
104
|
+
*
|
|
105
|
+
* ```text
|
|
106
|
+
* <commitment> OP_DROP <ika_xonly> OP_CHECKSIG
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* The commitment rides in the script purely to make the leaf — and so the
|
|
110
|
+
* address — unique per deposit; `OP_DROP` discards it at spend time. Only the
|
|
111
|
+
* dWallet key can satisfy the `OP_CHECKSIG`, and it signs untweaked.
|
|
112
|
+
*/
|
|
113
|
+
export function depositLeafScript(commitment, ikaXOnlyPubkey) {
|
|
114
|
+
if (commitment.length !== 32 || ikaXOnlyPubkey.length !== 32) {
|
|
115
|
+
throw new Error("commitment and ikaXOnlyPubkey must be 32 bytes");
|
|
116
|
+
}
|
|
117
|
+
const script = new Uint8Array(68);
|
|
118
|
+
script[0] = 0x20; // push 32 bytes
|
|
119
|
+
script.set(commitment, 1);
|
|
120
|
+
script[33] = 0x75; // OP_DROP
|
|
121
|
+
script[34] = 0x20; // push 32 bytes
|
|
122
|
+
script.set(ikaXOnlyPubkey, 35);
|
|
123
|
+
script[67] = 0xac; // OP_CHECKSIG
|
|
124
|
+
return script;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Derive a deposit address bound to `commitment`, spendable only by the pool's
|
|
128
|
+
* Ika dWallet via the script path.
|
|
129
|
+
*
|
|
130
|
+
* Returns everything the sweeper needs to spend it: a script-path witness is
|
|
131
|
+
* `[signature, leafScript, controlBlock]`.
|
|
132
|
+
*/
|
|
133
|
+
export function deriveDepositAddress(commitment, ikaXOnlyPubkey, network = "testnet") {
|
|
134
|
+
const leafScript = depositLeafScript(commitment, ikaXOnlyPubkey);
|
|
135
|
+
// One leaf, so the leaf hash IS the merkle root.
|
|
136
|
+
const leafHash = computeTapLeafHash(leafScript);
|
|
137
|
+
const { address, outputKey, parity } = deriveTaprootAddress(leafHash, network, DEPOSIT_NUMS_INTERNAL_KEY);
|
|
138
|
+
// <leaf_version | parity> || internal_key. No merkle path: single leaf.
|
|
139
|
+
const controlBlock = new Uint8Array(33);
|
|
140
|
+
controlBlock[0] = 0xc0 | parity;
|
|
141
|
+
controlBlock.set(DEPOSIT_NUMS_INTERNAL_KEY, 1);
|
|
142
|
+
return { address, outputKey, leafScript, leafHash, controlBlock };
|
|
143
|
+
}
|
|
92
144
|
/**
|
|
93
145
|
* Verify that a Taproot address is correctly derived from a commitment
|
|
94
146
|
*
|
package/package.json
CHANGED
|
@@ -1,73 +1,88 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utxopia/sdk",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
4
|
-
"description": "UTXOpia
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"repository": {
|
|
7
|
-
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/UTXOpia/utxopia-sdk.git"
|
|
9
|
-
},
|
|
10
|
-
"homepage": "https://github.com/UTXOpia/utxopia-sdk#readme",
|
|
11
|
-
"bugs": {
|
|
12
|
-
"url": "https://github.com/UTXOpia/utxopia-sdk/issues"
|
|
13
|
-
},
|
|
3
|
+
"version": "0.1.0-alpha.3",
|
|
4
|
+
"description": "UTXOpia SDK - Private Bitcoin across Solana and Sui",
|
|
14
5
|
"type": "module",
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
"files": [
|
|
20
|
-
"packages/sdk/dist",
|
|
21
|
-
"packages/btc-client/src",
|
|
22
|
-
"README.md",
|
|
23
|
-
"LICENSE"
|
|
24
|
-
],
|
|
25
|
-
"sideEffects": false,
|
|
26
|
-
"main": "./packages/sdk/dist/index.js",
|
|
27
|
-
"module": "./packages/sdk/dist/index.js",
|
|
28
|
-
"types": "./packages/sdk/dist/index.d.ts",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
29
9
|
"exports": {
|
|
30
10
|
".": {
|
|
31
|
-
"types": "./
|
|
32
|
-
"import": "./
|
|
33
|
-
"default": "./
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
34
14
|
},
|
|
35
15
|
"./prover": {
|
|
36
|
-
"types": "./
|
|
37
|
-
"import": "./
|
|
38
|
-
"default": "./
|
|
16
|
+
"types": "./dist/prover/index.d.ts",
|
|
17
|
+
"import": "./dist/prover/index.js",
|
|
18
|
+
"default": "./dist/prover/index.js"
|
|
39
19
|
},
|
|
40
20
|
"./prover/web": {
|
|
41
|
-
"types": "./
|
|
42
|
-
"import": "./
|
|
43
|
-
"default": "./
|
|
21
|
+
"types": "./dist/prover/web.d.ts",
|
|
22
|
+
"import": "./dist/prover/web.js",
|
|
23
|
+
"default": "./dist/prover/web.js"
|
|
44
24
|
},
|
|
45
25
|
"./prover/mobile": {
|
|
46
|
-
"types": "./
|
|
47
|
-
"import": "./
|
|
48
|
-
"default": "./
|
|
26
|
+
"types": "./dist/prover/mobile.d.ts",
|
|
27
|
+
"import": "./dist/prover/mobile.js",
|
|
28
|
+
"default": "./dist/prover/mobile.js"
|
|
29
|
+
},
|
|
30
|
+
"./stealth": {
|
|
31
|
+
"types": "./dist/stealth/index.d.ts",
|
|
32
|
+
"import": "./dist/stealth/index.js",
|
|
33
|
+
"default": "./dist/stealth/index.js"
|
|
49
34
|
},
|
|
50
35
|
"./bitcoin": {
|
|
51
|
-
"types": "./
|
|
52
|
-
"import": "./
|
|
53
|
-
"default": "./
|
|
36
|
+
"types": "./dist/bitcoin/index.d.ts",
|
|
37
|
+
"import": "./dist/bitcoin/index.js",
|
|
38
|
+
"default": "./dist/bitcoin/index.js"
|
|
54
39
|
},
|
|
55
|
-
"./
|
|
56
|
-
"types": "./
|
|
57
|
-
"import": "./
|
|
58
|
-
"default": "./
|
|
40
|
+
"./solana": {
|
|
41
|
+
"types": "./dist/solana/index.d.ts",
|
|
42
|
+
"import": "./dist/solana/index.js",
|
|
43
|
+
"default": "./dist/solana/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./watcher": {
|
|
46
|
+
"types": "./dist/watcher/index.d.ts",
|
|
47
|
+
"import": "./dist/watcher/index.js",
|
|
48
|
+
"default": "./dist/watcher/index.js"
|
|
49
|
+
},
|
|
50
|
+
"./watcher/web": {
|
|
51
|
+
"types": "./dist/watcher/web.d.ts",
|
|
52
|
+
"import": "./dist/watcher/web.js",
|
|
53
|
+
"default": "./dist/watcher/web.js"
|
|
59
54
|
},
|
|
60
|
-
"./
|
|
61
|
-
"types": "./
|
|
62
|
-
"import": "./
|
|
63
|
-
"default": "./
|
|
55
|
+
"./watcher/native": {
|
|
56
|
+
"types": "./dist/watcher/native.d.ts",
|
|
57
|
+
"import": "./dist/watcher/native.js",
|
|
58
|
+
"default": "./dist/watcher/native.js"
|
|
59
|
+
},
|
|
60
|
+
"./react": {
|
|
61
|
+
"types": "./dist/react/index.d.ts",
|
|
62
|
+
"import": "./dist/react/index.js",
|
|
63
|
+
"default": "./dist/react/index.js"
|
|
64
64
|
}
|
|
65
65
|
},
|
|
66
|
+
"files": [
|
|
67
|
+
"dist",
|
|
68
|
+
"src",
|
|
69
|
+
"circuits"
|
|
70
|
+
],
|
|
66
71
|
"scripts": {
|
|
67
|
-
"build": "
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
72
|
+
"build": "tsc",
|
|
73
|
+
"clean": "rm -rf dist",
|
|
74
|
+
"prepublishOnly": "bun run build",
|
|
75
|
+
"test": "bun test",
|
|
76
|
+
"test:unit": "bun test src/ test/commitment.test.ts test/commitment-onchain.test.ts",
|
|
77
|
+
"test:e2e": "bun test test/e2e/",
|
|
78
|
+
"test:e2e:devnet": "NETWORK=devnet bun test test/e2e/",
|
|
79
|
+
"test:e2e:claim": "bun test test/e2e/claim.test.ts",
|
|
80
|
+
"test:e2e:split": "bun test test/e2e/split.test.ts",
|
|
81
|
+
"test:e2e:partial": "bun test test/e2e/partial-public.test.ts",
|
|
82
|
+
"test:e2e:nullifier": "bun test test/e2e/nullifier.test.ts",
|
|
83
|
+
"test:e2e:tree": "bun test test/e2e/tree-consistency.test.ts",
|
|
84
|
+
"copy-circuits": "CIRCUITS_DIR=${UTXOPIA_CIRCUITS_DIR:-../../utxopia-circuits/circuits}; mkdir -p circuits && cp -r \"$CIRCUITS_DIR\"/build/* circuits/",
|
|
85
|
+
"e2e": "bun run scripts/e2e-mock-spv.ts"
|
|
71
86
|
},
|
|
72
87
|
"dependencies": {
|
|
73
88
|
"@magicblock-labs/ephemeral-rollups-kit": "0.16.2",
|
|
@@ -82,6 +97,12 @@
|
|
|
82
97
|
"circomlibjs": "^0.1.7",
|
|
83
98
|
"poseidon-lite": "0.3.0"
|
|
84
99
|
},
|
|
100
|
+
"devDependencies": {
|
|
101
|
+
"@solana/web3.js": "^1.98.4",
|
|
102
|
+
"@types/node": "^20.10.0",
|
|
103
|
+
"@types/react": "^19",
|
|
104
|
+
"typescript": "^5.3.0"
|
|
105
|
+
},
|
|
85
106
|
"peerDependencies": {
|
|
86
107
|
"react": ">=17.0.0",
|
|
87
108
|
"snarkjs": "^0.7.5"
|
|
@@ -94,15 +115,17 @@
|
|
|
94
115
|
"optional": true
|
|
95
116
|
}
|
|
96
117
|
},
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
|
|
118
|
+
"keywords": [
|
|
119
|
+
"solana",
|
|
120
|
+
"bitcoin",
|
|
121
|
+
"bridge",
|
|
122
|
+
"privacy",
|
|
123
|
+
"zkp",
|
|
124
|
+
"circom",
|
|
125
|
+
"groth16",
|
|
126
|
+
"snarkjs",
|
|
127
|
+
"taproot"
|
|
128
|
+
],
|
|
129
|
+
"author": "UTXOpia Team",
|
|
130
|
+
"license": "MIT"
|
|
108
131
|
}
|