@getcofund/protocol 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +414 -2
- package/dist/btc/index.d.ts +12 -0
- package/dist/btc/index.js +13 -0
- package/dist/btc/psbt.d.ts +121 -0
- package/dist/btc/psbt.js +377 -0
- package/dist/btc/reader.d.ts +42 -0
- package/dist/btc/reader.js +85 -0
- package/dist/btc/select.d.ts +48 -0
- package/dist/btc/select.js +59 -0
- package/dist/btc/spend-rules.d.ts +24 -0
- package/dist/btc/spend-rules.js +43 -0
- package/dist/btc/spend.d.ts +136 -0
- package/dist/btc/spend.js +180 -0
- package/dist/btc/types.d.ts +65 -0
- package/dist/btc/types.js +62 -0
- package/dist/btc/vault/bip341-nums.d.ts +35 -0
- package/dist/btc/vault/bip341-nums.js +121 -0
- package/dist/btc/vault/build.d.ts +5 -0
- package/dist/btc/vault/build.js +136 -0
- package/dist/btc/vault/canonical-order.d.ts +10 -0
- package/dist/btc/vault/canonical-order.js +18 -0
- package/dist/btc/vault/from-contract-id.d.ts +9 -0
- package/dist/btc/vault/from-contract-id.js +74 -0
- package/dist/btc/vault/helpers.d.ts +73 -0
- package/dist/btc/vault/helpers.js +129 -0
- package/dist/btc/vault/index.d.ts +21 -0
- package/dist/btc/vault/index.js +21 -0
- package/dist/btc/vault/limits.d.ts +9 -0
- package/dist/btc/vault/limits.js +9 -0
- package/dist/btc/vault/participant-order.d.ts +69 -0
- package/dist/btc/vault/participant-order.js +135 -0
- package/dist/btc/vault/script.d.ts +13 -0
- package/dist/btc/vault/script.js +39 -0
- package/dist/btc/vault/spend.d.ts +63 -0
- package/dist/btc/vault/spend.js +93 -0
- package/dist/btc/vault/tx-size.d.ts +66 -0
- package/dist/btc/vault/tx-size.js +71 -0
- package/dist/btc/vault/types.d.ts +49 -0
- package/dist/btc/vault/types.js +1 -0
- package/dist/btc/vault/vault-policy.d.ts +109 -0
- package/dist/btc/vault/vault-policy.js +213 -0
- package/dist/btc/vault/vaultContractUtil.d.ts +80 -0
- package/dist/btc/vault/vaultContractUtil.js +87 -0
- package/dist/btc/vault/xpub.d.ts +28 -0
- package/dist/btc/vault/xpub.js +41 -0
- package/dist/btc/witness.d.ts +101 -0
- package/dist/btc/witness.js +439 -0
- package/dist/btc-policies/activation.d.ts +76 -0
- package/dist/btc-policies/activation.js +153 -0
- package/dist/btc-policies/index.d.ts +7 -0
- package/dist/btc-policies/index.js +8 -0
- package/dist/btc-policies/policy.d.ts +55 -0
- package/dist/btc-policies/policy.js +210 -0
- package/dist/evm/abis/index.d.ts +10 -0
- package/dist/evm/abis/index.js +11 -0
- package/dist/evm/abis/policies.d.ts +279 -0
- package/dist/evm/abis/policies.js +363 -0
- package/dist/evm/abis/sponsor-guard.d.ts +201 -0
- package/dist/evm/abis/sponsor-guard.js +263 -0
- package/dist/evm/abis/state.d.ts +989 -0
- package/dist/evm/abis/state.js +1290 -0
- package/dist/evm/abis/users.d.ts +408 -0
- package/dist/evm/abis/users.js +532 -0
- package/dist/evm/abis/vault-factory.d.ts +92 -0
- package/dist/evm/abis/vault-factory.js +126 -0
- package/dist/evm/abis/vault.d.ts +343 -0
- package/dist/evm/abis/vault.js +444 -0
- package/dist/evm/address.d.ts +2 -0
- package/dist/evm/address.js +4 -0
- package/dist/evm/calls/common.d.ts +30 -0
- package/dist/evm/calls/common.js +51 -0
- package/dist/evm/calls/index.d.ts +11 -0
- package/dist/evm/calls/index.js +4 -0
- package/dist/evm/calls/policies.d.ts +25 -0
- package/dist/evm/calls/policies.js +173 -0
- package/dist/evm/calls/users.d.ts +61 -0
- package/dist/evm/calls/users.js +353 -0
- package/dist/evm/calls/vault.d.ts +25 -0
- package/dist/evm/calls/vault.js +184 -0
- package/dist/evm/chain.d.ts +74 -0
- package/dist/evm/chain.js +48 -0
- package/dist/evm/company-name.d.ts +46 -0
- package/dist/evm/company-name.js +64 -0
- package/dist/evm/deployment.d.ts +47 -0
- package/dist/evm/deployment.js +110 -0
- package/dist/evm/eip712.d.ts +271 -0
- package/dist/evm/eip712.js +224 -0
- package/dist/evm/index.d.ts +20 -0
- package/dist/evm/index.js +21 -0
- package/dist/evm/reads.d.ts +64 -0
- package/dist/evm/reads.js +131 -0
- package/dist/evm/signatures.d.ts +57 -0
- package/dist/evm/signatures.js +105 -0
- package/dist/evm/simulate/balances.d.ts +76 -0
- package/dist/evm/simulate/balances.js +201 -0
- package/dist/evm/simulate/describe.d.ts +79 -0
- package/dist/evm/simulate/describe.js +188 -0
- package/dist/evm/simulate/index.d.ts +12 -0
- package/dist/evm/simulate/index.js +13 -0
- package/dist/evm/simulate/own-node.d.ts +62 -0
- package/dist/evm/simulate/own-node.js +122 -0
- package/dist/evm/simulate/request.d.ts +86 -0
- package/dist/evm/simulate/request.js +235 -0
- package/dist/evm/simulate/revert.d.ts +29 -0
- package/dist/evm/simulate/revert.js +192 -0
- package/dist/evm/simulate/run.d.ts +51 -0
- package/dist/evm/simulate/run.js +214 -0
- package/dist/evm/stocks/decode-stock-swap.d.ts +32 -0
- package/dist/evm/stocks/decode-stock-swap.js +79 -0
- package/dist/evm/stocks/encode-swap.d.ts +45 -0
- package/dist/evm/stocks/encode-swap.js +45 -0
- package/dist/evm/stocks/index.d.ts +9 -0
- package/dist/evm/stocks/index.js +10 -0
- package/dist/evm/stocks/quote.d.ts +19 -0
- package/dist/evm/stocks/quote.js +46 -0
- package/dist/evm/stocks/stock-pools.d.ts +61 -0
- package/dist/evm/stocks/stock-pools.js +179 -0
- package/dist/evm/submitters.d.ts +32 -0
- package/dist/evm/submitters.js +105 -0
- package/dist/evm/types.d.ts +146 -0
- package/dist/evm/types.js +128 -0
- package/dist/keys/index.d.ts +6 -0
- package/dist/keys/index.js +7 -0
- package/dist/keys/keys.d.ts +63 -0
- package/dist/keys/keys.js +80 -0
- package/dist/keys/xpub-ownership.d.ts +10 -0
- package/dist/keys/xpub-ownership.js +13 -0
- package/package.json +60 -3
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { schnorr, secp256k1 } from "@noble/curves/secp256k1.js";
|
|
2
|
+
import { bytesToHex } from "@noble/hashes/utils";
|
|
3
|
+
import { HDKey } from "@scure/bip32";
|
|
4
|
+
import { generateMnemonic, mnemonicToSeedSync } from "@scure/bip39";
|
|
5
|
+
import { wordlist } from "@scure/bip39/wordlists/english";
|
|
6
|
+
import { generatePrivateKey, privateKeyToAccount, } from "viem/accounts";
|
|
7
|
+
import { BIP32_VERSIONS, COFUND_LEAF_INDEX } from "../btc/vault/xpub.js";
|
|
8
|
+
import { bitcoinSignedMessageHash } from "../btc-policies/activation.js";
|
|
9
|
+
import { btcXpubOwnershipChallenge } from "./xpub-ownership.js";
|
|
10
|
+
/** m/86'/coin'/0': the BIP-86 account a Cofund BTC vault derives from. */
|
|
11
|
+
function btcAccount(mnemonic, network) {
|
|
12
|
+
const root = HDKey.fromMasterSeed(mnemonicToSeedSync(mnemonic), BIP32_VERSIONS[network]);
|
|
13
|
+
return root.derive(`m/86'/${network === "mainnet" ? 0 : 1}'/0'`);
|
|
14
|
+
}
|
|
15
|
+
export function generateKeystore(network) {
|
|
16
|
+
const privateKey = generatePrivateKey();
|
|
17
|
+
const mnemonic = generateMnemonic(wordlist, 256);
|
|
18
|
+
return {
|
|
19
|
+
version: 1,
|
|
20
|
+
evm: { privateKey, address: privateKeyToAccount(privateKey).address },
|
|
21
|
+
btc: {
|
|
22
|
+
network,
|
|
23
|
+
mnemonic,
|
|
24
|
+
accountXpub: btcAccount(mnemonic, network).publicExtendedKey,
|
|
25
|
+
},
|
|
26
|
+
cofunds: {},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** The EVM key as a viem account: an EIP-712 signer (`TypedDataSigner`) and a wallet client's account. */
|
|
30
|
+
export function evmWallet(keystore) {
|
|
31
|
+
return privateKeyToAccount(keystore.evm.privateKey);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The xpub and its ownership proof: a BIP-340 signature by the account's /0/0
|
|
35
|
+
* key — the leaf vaults use — over the challenge bound to `userId` and the xpub.
|
|
36
|
+
*/
|
|
37
|
+
export function btcOwnershipProof(keystore, userId) {
|
|
38
|
+
const { mnemonic, network, accountXpub } = keystore.btc;
|
|
39
|
+
const leaf = btcAccount(mnemonic, network).deriveChild(0).deriveChild(0);
|
|
40
|
+
if (!leaf.privateKey) {
|
|
41
|
+
throw new Error("Could not derive the Bitcoin /0/0 key");
|
|
42
|
+
}
|
|
43
|
+
const signature = schnorr.sign(btcXpubOwnershipChallenge(userId, accountXpub), leaf.privateKey);
|
|
44
|
+
return { xpub: accountXpub, proof: bytesToHex(signature) };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The Cofund leaf's private key at `branch`, `m/86'/coin'/0'/<branch>/<leaf
|
|
48
|
+
* index>`: a vault derives every member's key in one tapleaf at that leaf's
|
|
49
|
+
* branch (0 for a single-leaf vault).
|
|
50
|
+
*/
|
|
51
|
+
function btcCofundLeafPrivateKey(account, branch) {
|
|
52
|
+
const leaf = account.deriveChild(branch).deriveChild(COFUND_LEAF_INDEX);
|
|
53
|
+
if (!leaf.privateKey) {
|
|
54
|
+
throw new Error("Could not derive the Bitcoin Cofund leaf key");
|
|
55
|
+
}
|
|
56
|
+
return leaf.privateKey;
|
|
57
|
+
}
|
|
58
|
+
/** The BTC key's Cofund leaf as a message signer: what a BTC policy approval is. */
|
|
59
|
+
export function btcMessageSigner(keystore) {
|
|
60
|
+
return {
|
|
61
|
+
signMessage(message) {
|
|
62
|
+
const { mnemonic, network } = keystore.btc;
|
|
63
|
+
// The BIP-137 hash is final: no second hash.
|
|
64
|
+
const signature = secp256k1.sign(bitcoinSignedMessageHash(message), btcCofundLeafPrivateKey(btcAccount(mnemonic, network), 0), { prehash: false });
|
|
65
|
+
return Promise.resolve(bytesToHex(signature));
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Zero aux randomness: BIP-340 permits it, and the app's signer uses it too. */
|
|
70
|
+
const ZERO_AUX = new Uint8Array(32);
|
|
71
|
+
/** The keystore's BTC key as a tapleaf signer; the seed is derived once, here. */
|
|
72
|
+
export function btcLeafSigner(keystore) {
|
|
73
|
+
const { mnemonic, network } = keystore.btc;
|
|
74
|
+
const account = btcAccount(mnemonic, network);
|
|
75
|
+
return {
|
|
76
|
+
network,
|
|
77
|
+
leafKey: (branch) => schnorr.getPublicKey(btcCofundLeafPrivateKey(account, branch)),
|
|
78
|
+
signDigest: (branch, digest) => schnorr.sign(digest, btcCofundLeafPrivateKey(account, branch), ZERO_AUX),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The message a registering BTC key must sign: bound to the user AND the
|
|
3
|
+
* xpub so a proof can't be replayed for another account or another key.
|
|
4
|
+
* The signing key is the /0/0 child of the submitted account xpub — the
|
|
5
|
+
* same leaf every vault ceremony derives — so a valid signature
|
|
6
|
+
* demonstrates control of the seed behind the xpub, not just knowledge of
|
|
7
|
+
* the (public) xpub string. Client signs it, server verifies it; both
|
|
8
|
+
* sides import this one definition.
|
|
9
|
+
*/
|
|
10
|
+
export declare function btcXpubOwnershipChallenge(userId: string, xpub: string): Uint8Array;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { sha256 } from "@noble/hashes/sha2";
|
|
2
|
+
/**
|
|
3
|
+
* The message a registering BTC key must sign: bound to the user AND the
|
|
4
|
+
* xpub so a proof can't be replayed for another account or another key.
|
|
5
|
+
* The signing key is the /0/0 child of the submitted account xpub — the
|
|
6
|
+
* same leaf every vault ceremony derives — so a valid signature
|
|
7
|
+
* demonstrates control of the seed behind the xpub, not just knowledge of
|
|
8
|
+
* the (public) xpub string. Client signs it, server verifies it; both
|
|
9
|
+
* sides import this one definition.
|
|
10
|
+
*/
|
|
11
|
+
export function btcXpubOwnershipChallenge(userId, xpub) {
|
|
12
|
+
return sha256(new TextEncoder().encode(`cofund-btc-xpub-ownership|v1|${userId}|${xpub}`));
|
|
13
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,63 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getcofund/protocol",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The Cofund protocol on chain: Bitcoin vaults, EIP-712 messages, call simulation and key derivation. Chain only: the consumer brings the deployment, readers, signers and submitters.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/Strata-Labs/cofund-webapp.git",
|
|
9
|
+
"directory": "packages/protocol"
|
|
10
|
+
},
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"type": "module",
|
|
13
|
+
"exports": {
|
|
14
|
+
"./evm": {
|
|
15
|
+
"types": "./dist/evm/index.d.ts",
|
|
16
|
+
"default": "./dist/evm/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./btc": {
|
|
19
|
+
"types": "./dist/btc/index.d.ts",
|
|
20
|
+
"default": "./dist/btc/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./btc-policies": {
|
|
23
|
+
"types": "./dist/btc-policies/index.d.ts",
|
|
24
|
+
"default": "./dist/btc-policies/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./keys": {
|
|
27
|
+
"types": "./dist/keys/index.d.ts",
|
|
28
|
+
"default": "./dist/keys/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"README.md"
|
|
37
|
+
],
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=20"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@noble/curves": "^2.0.0",
|
|
43
|
+
"@noble/hashes": "^1.8.0",
|
|
44
|
+
"@scure/base": "^1.2.5",
|
|
45
|
+
"@scure/bip32": "^1.7.0",
|
|
46
|
+
"@scure/bip39": "^1.6.0",
|
|
47
|
+
"@scure/btc-signer": "^2.0.0",
|
|
48
|
+
"viem": "^2.56.0",
|
|
49
|
+
"zod": "^4.3.6"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "24.10.13",
|
|
53
|
+
"esbuild": "0.28.2",
|
|
54
|
+
"typescript": "5.9.3",
|
|
55
|
+
"vitest": "^4.1.5"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsc",
|
|
59
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p test",
|
|
60
|
+
"test": "vitest run",
|
|
61
|
+
"smoke": "bash scripts/smoke-pack.sh"
|
|
62
|
+
}
|
|
6
63
|
}
|