This commit is contained in:
Alex 2025-04-02 17:07:30 +03:00
commit 5e2789b43e
168 changed files with 21184 additions and 0 deletions

View File

@ -0,0 +1,2 @@
calls:
- !include packages/market-maker.cm/deploy/.calls-package.yaml

View File

@ -0,0 +1,134 @@
devnet:
mnemonic: priority supply couple broccoli balcony sort flag keep original wrong pottery version
shardToWrite: DEVNET_L1A
shardToExecute: DEVNET_L1A
endpoint: https://api-devnet.coinweb.io/wallet
bootstrapConfig:
dataHasher: data_hasher_v2
controller: controller_v2
dependencies:
- decompressor_v2
- data_hasher
replicateConfig: &dev_replicate
replicator: replicant_devnet v0.1.1
replicas:
- shard: devb
interpreters:
- data_hasher
- data_hasher_v2
- std_js_contract_v0
templates:
- jump-listener.cm v0.1.8
instances:
- jump_listener_production v0.1.8
- shard: tbtc
interpreters:
- data_hasher
- data_hasher_v2
- std_js_contract_v0
templates:
- jump-listener.cm v0.1.8
instances:
- jump_listener_production v0.1.8
unsafe: true
gitRemoteLockIndexRepo: git@gitlab.com:coinweb/cweb-dapp-index.git
pathToIndexFile: .cweb-config/dapp-ecosystem-devnet.yaml
pathToLockIndexFile: .dapp-ecosystem-lock-devnet.yaml
pathToRawActionFile: ./.unfiltered-actions-devnet.yaml
pathToFilteredActionFile: .actions-devnet.yaml
packageRegistry: 'https://npm.coinweb.io'
production:
mnemonic: priority supply couple broccoli balcony sort flag keep original wrong pottery version
shardToWrite: ELROND
shardToExecute: BNB
endpoint: https://api-cloud.coinweb.io/wallet
bootstrapConfig:
dataHasher: data_hasher_v2
controller: controller_v2
dependencies:
- decompressor_v2
- data_hasher
replicateConfig: &prod_replicate
replicator: replicant_production v0.1.1
replicas:
- shard: eth
interpreters:
- data_hasher
- data_hasher_v2
- std_js_contract_v0
templates:
- jump-listener.cm v0.1.8
instances:
- jump_listener_production v0.1.8
- shard: btc
interpreters:
- data_hasher
- data_hasher_v2
- std_js_contract_v0
templates:
- jump-listener.cm v0.1.8
- jump-forwarder.cm v0.1.5
instances:
- jump_listener_production v0.1.8
- jump_forwarder_production v0.1.5
- shard: egld
interpreters:
- data_hasher
- data_hasher_v2
- std_js_contract_v0
templates:
- jump-forwarder.cm v0.1.5
instances:
- jump_forwarder_production v0.1.5
- shard: trx
interpreters:
- data_hasher
- data_hasher_v2
- std_js_contract_v0
templates:
- jump-listener.cm v0.1.8
instances:
- jump_listener_production v0.1.8
unsafe: true
gitRemoteLockIndexRepo: git@gitlab.com:coinweb/cweb-dapp-index.git
pathToIndexFile: .cweb-config/dapp-ecosystem-prod.yaml
pathToLockIndexFile: .dapp-ecosystem-lock-prod.yaml
pathToRawActionFile: ./.unfiltered-actions-prod.yaml
pathToFilteredActionFile: .actions-prod.yaml
packageRegistry: 'https://npm.coinweb.io'
test:
mnemonic: priority supply couple broccoli balcony sort flag keep original wrong pottery version
shardToWrite: DEVNET_L1A
shardToExecute: DEVNET_L1A
endpoint: https://api-devblue.coinhq.store/wallet
bootstrapConfig:
dataHasher: data_hasher_v2
controller: controller_v2
dependencies:
- decompressor_v2
- data_hasher
replicateConfig:
replicator: replicant_production v0.1.1
replicas: []
unsafe: true
gitRemoteLockIndexRepo: git@gitlab.com:coinweb/cweb-dapp-index.git
pathToIndexFile: .cweb-config/dapp-ecosystem-test.yaml
pathToLockIndexFile: .dapp-ecosystem-lock-test.yaml
pathToRawActionFile: ./.unfiltered-actions-test.yaml
pathToFilteredActionFile: .actions-tests.yaml
packageRegistry: 'https://npm.coinweb.io'

View File

@ -0,0 +1,38 @@
import fsSync from 'fs';
import yaml from 'js-yaml';
import path from 'path';
const workdirPath = process.cwd();
// Define a custom tag for including external YAML files
const extendedSchema = yaml.DEFAULT_SCHEMA.extend([
new yaml.Type('!include', {
kind: 'scalar',
resolve: function (data) {
return typeof data === 'string';
},
construct: function (filePath) {
try {
const content = fsSync.readFileSync(filePath, 'utf8');
return yaml.load(content, { schema: yaml.DEFAULT_SCHEMA });
} catch (error) {
console.log('\n');
console.log('Did you forget to build your contract modules?');
console.log('Run \x1b[36myarn build\x1b[0m before deploying.');
console.log('\n');
console.error(error);
process.exit(-1);
}
},
}),
]);
const callsTemplateJSON = yaml.load(
fsSync.readFileSync(path.join(workdirPath, '/.cweb-config/calls-template.yaml'), 'utf8'),
{ schema: extendedSchema }
);
fsSync.writeFileSync(path.join(workdirPath, '/.cweb-config/calls.yaml'), yaml.dump(callsTemplateJSON), {
encoding: 'utf8',
});

View File

@ -0,0 +1,4 @@
known_dapps_index:
url: >-
https://gitlab.com/api/v4/projects/47807501/packages/generic/contract_indexes/0.0.9/in_house_ecosystem_index.yaml
blake3: e84b9bf978b694e3656c3639d4c84eedf21ee65e61fe95ebd2c06c11890d561c

View File

@ -0,0 +1,265 @@
# This is a "index source" that specifies the dApp world as you see it.
#
# This index defines what interpreters, contract templates etc you want
# to use, and what they should be called.
#
# You can include external sources for this information in the `includes`
# section, and you include your own smart contract in the `contract_templates`
# section.
#
includes:
- url: >-
https://gitlab.com/coinweb/cweb-dapp-index/-/raw/b534ebc0dbe7faa3458f11e2bc19553ab70bc317/dapp_lock_index.yaml
blake3: 48c6cd4b1b9252f2513efca47a0a8bd2f61417c6adc6bcd9d7e30521e735545e
interpreters: {}
contract_templates:
# Our contract module. The contract module is an npm package created in the `dist/out`
# directory using the `yarn build` and `yarn pack` commands.
- file:///./packages/dex-app.cm/dist/out/my-contract-module.tgz
- file:///./packages/market-maker.cm/dist/out/my-contract-module.tgz
contract_instances:
- alias: btc_offer_maker 0.0.90+devnet
template: dex-app.cm v0.0.90+test
parameters:
content:
l1_type: 1
shard: tbtc
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 0
order_life_time: 604800000
close_order_timeout: 300000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: eth_offer_maker 0.0.90+devnet
template: dex-app.cm v0.0.90+test
parameters:
content:
shard: deva
l1_type: 0
l1_contract_address: '0x7F0055241779898b7aE8325217F690C843AfdD84'
l1_transfer_event_signature: '0xc57b8d4564150cb20d03b08bce9ee8d27b7fa55b10337806be888ea3803b019e'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 0
order_life_time: 604800000
close_order_timeout: 300000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: bnb_offer_maker 0.0.90+devnet
template: dex-app.cm v0.0.90+test
parameters:
content:
shard: devb
l1_type: 0
l1_contract_address: '0x7F0055241779898b7aE8325217F690C843AfdD84'
l1_transfer_event_signature: '0xc57b8d4564150cb20d03b08bce9ee8d27b7fa55b10337806be888ea3803b019e'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 0
order_life_time: 604800000
close_order_timeout: 300000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: usdt_eth_offer_maker 0.0.90+devnet
template: dex-app.cm v0.0.90+test
parameters:
content:
shard: deva
l1_type: 0
l1_contract_address: '0xe6D28e11e2D65439343551127D51770f079a3427'
l1_transfer_event_signature: '0xc57b8d4564150cb20d03b08bce9ee8d27b7fa55b10337806be888ea3803b019e'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 0
order_life_time: 604800000
close_order_timeout: 300000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: usdt_bnb_offer_maker 0.0.90+devnet
template: dex-app.cm v0.0.90+test
parameters:
content:
shard: devb
l1_type: 0
l1_contract_address: '0xe6D28e11e2D65439343551127D51770f079a3427'
l1_transfer_event_signature: '0xc57b8d4564150cb20d03b08bce9ee8d27b7fa55b10337806be888ea3803b019e'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 0
order_life_time: 604800000
close_order_timeout: 300000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: btc_pact_maker 0.0.85+devnet
template: market-maker.cm v0.0.85+test
parameters:
content:
l1_type: 1
shard: tbtc
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
collateral_percentage_Int: 100
owner_min_fee_Hex: '0x0'
owner_percentage_fee_Int: 0
order_life_time: 604800000
pact_life_time: 10800000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: eth_pact_maker 0.0.85+devnet
template: market-maker.cm v0.0.85+test
parameters:
content:
l1_type: 0
shard: deva
l1_contract_address: '0x5b50845B94fC47c6172d9ab90845D3613e36Aed5'
l1_transfer_event_signature: '0xa42a1fb0456e2cc8990290e31b24166458f3ac8beb986ab6c26f47fdc486d594'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
collateral_percentage_Int: 100
owner_min_fee_Hex: '0x0'
owner_percentage_fee_Int: 0
order_life_time: 604800000
pact_life_time: 10800000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: bnb_pact_maker 0.0.85+devnet
template: market-maker.cm v0.0.85+test
parameters:
content:
l1_type: 0
shard: devb
l1_contract_address: '0x5b50845B94fC47c6172d9ab90845D3613e36Aed5'
l1_transfer_event_signature: '0xa42a1fb0456e2cc8990290e31b24166458f3ac8beb986ab6c26f47fdc486d594'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
collateral_percentage_Int: 100
owner_min_fee_Hex: '0x0'
owner_percentage_fee_Int: 0
order_life_time: 604800000
pact_life_time: 10800000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: usdt_eth_dex_pact_maker 0.0.85+devnet
template: market-maker.cm v0.0.85+test
parameters:
content:
l1_type: 0
shard: deva
l1_contract_address: '0x81b6711C0AeA07a60f65e92a5678c516d84cA467'
l1_transfer_event_signature: '0xa42a1fb0456e2cc8990290e31b24166458f3ac8beb986ab6c26f47fdc486d594'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
collateral_percentage_Int: 100
owner_min_fee_Hex: '0x0'
owner_percentage_fee_Int: 0
order_life_time: 604800000
pact_life_time: 10800000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: usdt_bnb_pact_maker 0.0.85+devnet
template: market-maker.cm v0.0.85+test
parameters:
content:
l1_type: 0
shard: devb
l1_contract_address: '0x81b6711C0AeA07a60f65e92a5678c516d84cA467'
l1_transfer_event_signature: '0xa42a1fb0456e2cc8990290e31b24166458f3ac8beb986ab6c26f47fdc486d594'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
collateral_percentage_Int: 100
owner_min_fee_Hex: '0x0'
owner_percentage_fee_Int: 0
order_life_time: 604800000
pact_life_time: 10800000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom

View File

@ -0,0 +1,264 @@
# This is a "index source" that specifies the dApp world as you see it.
#
# This index defines what interpreters, contract templates etc you want
# to use, and what they should be called.
#
# You can include external sources for this information in the `includes`
# section, and you include your own smart contract in the `contract_templates`
# section.
#
includes:
- url: >-
https://gitlab.com/coinweb/cweb-dapp-index/-/raw/35d7542b81d884adb899ea95f1433fe59b012a6c/dapp_lock_index.yaml
blake3: 0e8f57c2c939f9cccf6912c2fb7994bb7095a1f10bef585296dba4263eb76211
interpreters: {}
contract_templates:
# Our contract module. The contract module is an npm package created in the `dist/out`
# directory using the `yarn build` and `yarn pack` commands.
- file:///./packages/dex-app.cm/dist/out/my-contract-module.tgz
- file:///./packages/market-maker.cm/dist/out/my-contract-module.tgz
contract_instances:
- alias: btc_offer_maker 0.0.70+prod
template: dex-app.cm v0.0.70+test
parameters:
content:
l1_type: 1
shard: btc
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 0
order_life_time: 604800000
close_order_timeout: 180000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: eth_offer_maker 0.0.70+prod
template: dex-app.cm v0.0.70+test
parameters:
content:
shard: eth
l1_type: 0
l1_contract_address: "0x371b5eBEadf34Da576E3E604b70f8580EF383476"
l1_transfer_event_signature: '0xc57b8d4564150cb20d03b08bce9ee8d27b7fa55b10337806be888ea3803b019e'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 0
order_life_time: 604800000
close_order_timeout: 180000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: bnb_offer_maker 0.0.70+prod
template: dex-app.cm v0.0.70+test
parameters:
content:
shard: bnb
l1_type: 0
l1_contract_address: '0x0FD1b7B27d48C66A6d74C31469298dad6a80fD06'
l1_transfer_event_signature: '0xc57b8d4564150cb20d03b08bce9ee8d27b7fa55b10337806be888ea3803b019e'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 0
order_life_time: 604800000
close_order_timeout: 180000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: usdt_eth_offer_maker 0.0.70+prod
template: dex-app.cm v0.0.70+test
parameters:
content:
shard: eth
l1_type: 0
l1_contract_address: '0xDe69576fB589C2F64Fd47E94381E413407306575'
l1_transfer_event_signature: '0xc57b8d4564150cb20d03b08bce9ee8d27b7fa55b10337806be888ea3803b019e'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 0
order_life_time: 604800000
close_order_timeout: 180000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: usdt_bnb_offer_maker 0.0.70+prod
template: dex-app.cm v0.0.70+test
parameters:
content:
shard: bnb
l1_type: 0
l1_contract_address: '0x55549F93d478C6b0DEDE5723Ca825aF680d454F8'
l1_transfer_event_signature: '0xc57b8d4564150cb20d03b08bce9ee8d27b7fa55b10337806be888ea3803b019e'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 0
order_life_time: 604800000
close_order_timeout: 180000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: btc_pact_maker 0.0.71+prod
template: market-maker.cm v0.0.71+test
parameters:
content:
l1_type: 1
shard: btc
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
collateral_percentage_Int: 100
owner_min_fee_Hex: '0x0'
owner_percentage_fee_Int: 0
order_life_time: 604800000
pact_life_time: 10800000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: eth_pact_maker 0.0.71+prod
template: market-maker.cm v0.0.71+test
parameters:
content:
l1_type: 0
shard: eth
l1_contract_address: "0xA3C365C57867B495d2fA1A2A45AAfD6F12e635e4"
l1_transfer_event_signature: '0xa42a1fb0456e2cc8990290e31b24166458f3ac8beb986ab6c26f47fdc486d594'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
collateral_percentage_Int: 100
owner_min_fee_Hex: "0x0"
owner_percentage_fee_Int: 0
order_life_time: 604800000
pact_life_time: 10800000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: bnb_pact_maker 0.0.71+prod
template: market-maker.cm v0.0.71+test
parameters:
content:
l1_type: 0
shard: bnb
l1_contract_address: '0x61C162a21dDc45D7d405a7a2766dA8AcEE7c70aa'
l1_transfer_event_signature: '0xa42a1fb0456e2cc8990290e31b24166458f3ac8beb986ab6c26f47fdc486d594'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
collateral_percentage_Int: 100
owner_min_fee_Hex: '0x0'
owner_percentage_fee_Int: 0
order_life_time: 604800000
pact_life_time: 10800000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: usdt_eth_pact_maker v0.0.71+prod
template: market-maker.cm v0.0.71+test
parameters:
content:
l1_type: 0
shard: eth
l1_contract_address: '0xa9D53f7B4836a595db7E11A7f92F9EF3810E04B6'
l1_transfer_event_signature: '0xa42a1fb0456e2cc8990290e31b24166458f3ac8beb986ab6c26f47fdc486d594'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
collateral_percentage_Int: 100
owner_min_fee_Hex: '0x0'
owner_percentage_fee_Int: 0
order_life_time: 604800000
pact_life_time: 10800000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: usdt_bnb_pact_maker 0.0.71+prod
template: market-maker.cm v0.0.71+test
parameters:
content:
l1_type: 0
shard: bnb
l1_contract_address: '0x8DA7D02A181AEac031B9ee66b238f5CBdE249241'
l1_transfer_event_signature: '0xa42a1fb0456e2cc8990290e31b24166458f3ac8beb986ab6c26f47fdc486d594'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
collateral_percentage_Int: 100
owner_min_fee_Hex: '0x0'
owner_percentage_fee_Int: 0
order_life_time: 604800000
pact_life_time: 10800000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom

View File

@ -0,0 +1,102 @@
# This is a "index source" that specifies the dApp world as you see it.
#
# This index defines what interpreters, contract templates etc you want
# to use, and what they should be called.
#
# You can include external sources for this information in the `includes`
# section, and you include your own smart contract in the `contract_templates`
# section.
#
includes:
- url: >-
https://gitlab.com/coinweb/cweb-dapp-index/-/raw/5d52c2c4c39fbe74b7e86e9a9c463240df69b01d/dapp_lock_index.yaml
blake3: a576de68122e704240acc7efe813d52cecd1519fab1078db537ed4b59da0f9ba
use:
- dex-app.cm v0.0.67+test
- eth_offer_maker 0.0.67+devnet
- jump-listener.cm v0.0.5
interpreters: {}
contract_templates:
# Our contract module. The contract module is an npm package created in the `dist/out`
# directory using the `yarn build` and `yarn pack` commands.
- file:///./packages/dex-app.cm/dist/out/my-contract-module.tgz
- file:///./packages/market-maker.cm/dist/out/my-contract-module.tgz
contract_instances:
- alias: eth_offer_maker 0.0.67+remote
template: dex-app.cm v0.0.67+remote
parameters:
content:
shard: deva
l1_type: 0
l1_contract_address: '0x6e00389D89B8A85cAc7f0891300E28020D868F52'
l1_transfer_event_signature: '0x5f7c9ad4d0773734853dba78fa92bd33af346833ce0b6310f7b1ceeb8a52ac3a'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 1
order_life_time: 604800000
close_order_timeout: 300000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: bnb_offer_maker 0.0.67+remote
template: dex-app.cm v0.0.67+remote
parameters:
content:
shard: devb
l1_type: 0
l1_contract_address: '0x381683E82B9B3aD801B8Ee594BaFCD5e446610CD'
l1_transfer_event_signature: '0x5f7c9ad4d0773734853dba78fa92bd33af346833ce0b6310f7b1ceeb8a52ac3a'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
owner_min_fee: '0x0'
owner_percentage_fee: 5
order_life_time: 604800000
close_order_timeout: 300000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom
- alias: eth_dex_pact_maker v0.0.69+test
template: market-maker.cm v0.0.69+test
parameters:
content:
l1_type: 0
shard: deva
l1_contract_address: '0x4d8124960d5D8Ca9211386E2d330373Ae8b86706'
l1_transfer_event_signature: '0xdaccd7e57af38151956717859e819d92af68eb0b7b8402730f6ba2130c843f33'
owner:
auth: EcdsaContract
payload: 036d9316445a2a9823919f1df9e9fc932550078fe06b772a676eaaba33932432a1
collateral_percentage_Int: 100
owner_min_fee_Hex: '0x0'
owner_percentage_fee_Int: 0
order_life_time: 604800000
pact_life_time: 1080000
jump_contract_id: '0xcb5f8ee92bf9fe08f59a6997f3def2405f5bab46d0468d0bff1ff359c54192a5'
jump_contract_method: 'JUMP-AND-WAIT'
logs:
- method-name
- provided-cweb
- method-args
- contract-args
- custom

1
.env.production Normal file
View File

@ -0,0 +1 @@
PRODUCTION_MNEMONIC="sea total mirror fat opera swear fox history such assist picture snack"

7
.env.yarn Normal file
View File

@ -0,0 +1,7 @@
NPM_USERNAME=
NPM_PASSWORD=
# This is needed when working with WASM modules (nodeLinker: node-modules is mandatory)
NODE_OPTIONS="--experimental-wasm-modules --no-warnings=ExperimentalWarning --max-old-space-size=8192"
REGISTRATION_PROFILE=devnet

52
.gitignore vendored Normal file
View File

@ -0,0 +1,52 @@
node_modules
cweb_dist
tmp
.cweb_tool
**/yarn-error.log
**/dist
**/.DS_Store
**/.calls-package.yaml
.dapp-ecosystem-lock*.yaml
.vscode/*
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
.aider*
unsafe_wallet_mnenonic
unsafe_wallet_mnemonic
.unfiltered-actions*.yaml
.actions-*.yaml
install-state.gz
*.cast
.devcontainer/gid
.devcontainer/uid
.env.yarn.devnet
!.env.yarn
.cweb-config/calls.yaml
tests_data/
.cweb-config/config.yaml
.actions.yaml
.actions-prod.yaml
.actions-devnet-blue.yaml
.actions-devnet.yaml
prepared-state.json
# Hardhat
hardhat/cache
hardhat/artifacts
hardhat/typechain-types
hardhat/.env
hardhat/coverage
hardhat/coverage.json

25
.prettierrc.mjs Normal file
View File

@ -0,0 +1,25 @@
// prettier.config.js, .prettierrc.js, prettier.config.mjs, or .prettierrc.mjs
/** @type {import("prettier").Config} */
const config = {
semi: true,
singleQuote: true,
tabWidth: 2,
printWidth: 120,
trailingComma: 'es5',
endOfLine: 'auto',
overrides: [
{
files: ['*.mdx', '*.md'],
options: {
printWidth: 80,
proseWrap: 'always',
},
},
],
singleAttributePerLine: false,
tailwindFunctions: ['clsx', 'cva'],
plugins: ['prettier-plugin-tailwindcss'],
};
export default config;

935
.yarn/releases/yarn-4.7.0.cjs vendored Executable file

File diff suppressed because one or more lines are too long

14
.yarnrc.yml Normal file
View File

@ -0,0 +1,14 @@
checksumBehavior: update
injectEnvironmentFiles:
- .env.yarn
- .env.yarn.devnet?
nodeLinker: node-modules
npmScopes:
coinweb:
npmPublishRegistry: "https://npm.coinweb.io/"
npmRegistryServer: "https://npm.coinweb.io/"
yarnPath: .yarn/releases/yarn-4.7.0.cjs

169
eslint.config.mjs Normal file
View File

@ -0,0 +1,169 @@
import eslint from '@eslint/js';
import eslintConfigPrettier from 'eslint-config-prettier';
import * as importPlugin from 'eslint-plugin-import';
import eslintPluginPrettier from 'eslint-plugin-prettier/recommended';
import eslintPluginReact from 'eslint-plugin-react';
import globals from 'globals';
import tseslint from 'typescript-eslint';
export default tseslint.config(
// config with just ignores is the replacement for `.eslintignore`
{
ignores: [
'**/.*',
'**/node_modules/**',
'**/hardhat/**',
'**/dist/**',
'**/public/**',
'**/cweb_tool/**',
'**/cweb_dist/**',
'**/build/**',
'**/dapp-ui/src/pages/Bot/**',
'**/dapp-ui/src/pages/BotHedging/**',
'**/dapp-ui/src/pages/SwapTool/**',
'**/market-maker.cm/perf_test/onchain.cjs',
],
},
// rest of the config by module
// eslint
{
rules: {
...eslint.configs.recommended.rules,
'no-console': ['warn', { allow: ['error'] }],
'no-bitwise': 'error',
'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
},
},
{
files: ['**/*.js', '**/*.mjs'],
languageOptions: {
sourceType: 'module',
parserOptions: { ecmaVersion: 'latest' },
globals: { ...globals.node, ...globals.browser },
},
},
{
files: ['**/*.cjs'],
languageOptions: {
sourceType: 'commonjs',
parserOptions: { ecmaVersion: 'latest' },
globals: { ...globals.node, ...globals.browser },
},
},
// prettier
eslintPluginPrettier,
eslintConfigPrettier,
// typescript
...tseslint.configs.recommendedTypeChecked.map((config) => ({
...config,
files: ['**/*.ts', '**/*.tsx'], // We use TS config only for TS files
})),
{
files: ['**/*.ts', '**/*.tsx'], // We use TS config only for TS files
plugins: {
'@typescript-eslint': tseslint.plugin,
},
languageOptions: {
parser: tseslint.parser,
parserOptions: {
project: ['tsconfig.eslint.json', './packages/*/tsconfig.json'],
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-misused-promises': ['error', { checksVoidReturn: false }],
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'off',
'@typescript-eslint/no-unsafe-enum-comparison': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/restrict-template-expressions': 'off',
'@typescript-eslint/no-base-to-string': 'warn',
'@typescript-eslint/naming-convention': [
'warn',
{
selector: 'variable',
types: ['boolean'],
format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
prefix: ['is', 'should', 'has', 'can', 'did', 'use'],
filter: {
regex: '^_',
match: false,
},
},
{
selector: 'variable',
format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
filter: {
regex: '^_',
match: false,
},
},
],
'@typescript-eslint/explicit-function-return-type': [
'off',
{
allowTypedFunctionExpressions: true,
},
],
},
},
// import-plugin
{
...importPlugin.flatConfigs.recommended,
rules: {
'import/named': 'off',
'import/newline-after-import': 'error',
'import/order': [
'warn',
{
'newlines-between': 'always',
alphabetize: { order: 'asc' },
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
pathGroupsExcludedImportTypes: ['react'],
pathGroups: [
{ pattern: 'react', group: 'builtin', position: 'before' },
{ pattern: '@/**', group: 'external', position: 'after' },
],
},
],
},
},
{
...importPlugin.flatConfigs.typescript,
settings: {
alias: {
map: [['@', './src']],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
},
},
// react, dapp-ui
{
files: ['packages/dapp-ui/src/**/*.jsx', 'packages/dapp-ui/src/**/*.tsx'],
...eslintPluginReact.configs.flat.recommended,
settings: { react: { version: 'detect' } },
rules: {
...eslintPluginReact.configs.flat.recommended.rules,
'react/react-in-jsx-scope': 'off',
'react/prop-types': 'off',
},
}
);

78
package.json Normal file
View File

@ -0,0 +1,78 @@
{
"name": "dex-tx",
"packageManager": "yarn@4.7.0",
"private": true,
"workspaces": [
"packages/*"
],
"scripts": {
"build": "yarn build:cm && yarn build:non-cm",
"build:production": "yarn build:cm && yarn workspace dapp-ui build:production",
"build:cm": "yarn workspaces foreach -Ap --include 'packages/*.cm' --include 'packages/cwap-cm-*' run build",
"build:non-cm": "yarn workspaces foreach -Ap --include 'packages/*' --exclude 'packages/*.cm' run build",
"create-index": "cweb-tool create-index -c ./.cweb-config/config.yaml --profile $REGISTRATION_PROFILE",
"publish-index": "cweb-tool publish-index -c ./.cweb-config/config.yaml --profile $REGISTRATION_PROFILE",
"deploy-contracts": "yarn publish-actions",
"call-contracts": "yarn call-contracts:prepare && yarn call-contracts:invoke",
"call-contracts:prepare": "yarn workspaces foreach --all run prepare-for-package && yarn node ./.cweb-config/create-calls.mjs",
"call-contracts:invoke": "cweb-tool call .cweb-config/calls.yaml -c ./.cweb-config/config.yaml --profile $REGISTRATION_PROFILE",
"execute-actions": "echo \"*** THIS MIGHT TAKE A LONG TIME ***\"; sleep 1; cweb-tool execute-actions -c ./.cweb-config/config.yaml --profile $REGISTRATION_PROFILE",
"filter-actions": "cweb-tool filter-actions -c ./.cweb-config/config.yaml --profile $REGISTRATION_PROFILE",
"gather-actions": "cweb-tool gather-actions -c ./.cweb-config/config.yaml --profile $REGISTRATION_PROFILE",
"publish-actions": "cweb-tool publish -c ./.cweb-config/config.yaml --profile $REGISTRATION_PROFILE",
"clean": "yarn clean:me && yarn workspaces foreach -Ap run clean",
"clean:me": "rm -rf .dapp-ecosystem-lock*.yaml .unfiltered-actions*.yaml .actions*.yaml",
"test": "yarn workspaces foreach -Ap run test",
"test:prepare": "yarn simulate && yarn workspaces foreach -Ap run test:prepare",
"simulate": "cweb-tool simulate .dapp-ecosystem-lock-test.yaml prepared-state.json -c ./.cweb-config/config.yaml --profile $REGISTRATION_PROFILE",
"setup-ide:vscode": "yarn dlx @yarnpkg/sdks vscode",
"install:with-node-modules": "yarn config set nodeLinker node-modules && yarn install",
"preinstall": "./scripts/preinstall.env.sh",
"dev": "yarn workspaces foreach -Apiv run dev",
"prepare": "husky",
"lint": "yarn workspaces foreach -Ap run lint",
"typecheck": "yarn workspaces foreach -Ap run typecheck",
"update-env": "node scripts/update-ui-env.js",
"g:tsc": "cd $INIT_CWD && tsc",
"g:cweb-tool": "cd $INIT_CWD && cweb-tool",
"g:lint": "cd $INIT_CWD && eslint",
"g:vitest": "cd $INIT_CWD && vitest",
"g:lint-staged": "cd $INIT_CWD && lint-staged",
"publish:lib": "yarn workspaces foreach -Ap --include 'packages/cwap-cm-*' run publish:lib"
},
"resolutions": {
"@coinweb/cweb-tool": "2.0.22",
"@coinweb/wallet-lib": "0.1.116",
"@coinweb/self-register": "0.1.3",
"@coinweb/claims-client": "0.1.6-debug",
"@coinweb/contract-kit": "0.2.6",
"@coinweb/testing-sdk": "0.0.9-remote",
"@coinweb/minimal-sdk": "1.2.21"
},
"devDependencies": {
"@coinweb/cweb-tool": "2.0.22",
"@coinweb/minimal-sdk": "1.2.21",
"@coinweb/testing-sdk": "0.0.10-mutex",
"@eslint/js": "^9.17.0",
"@types/node": "^22.10.5",
"envsub": "^4.1.0",
"eslint": "^9.17.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.37.3",
"husky": "^9.1.7",
"js-yaml": "^4.1.0",
"lint-staged": "^15.3.0",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.9",
"typescript": "^5.7.3",
"typescript-eslint": "^8.19.1",
"vitest": "^2.1.8",
"yaml": "^2.7.0"
},
"version": "0.0.0",
"description": "",
"author": "CWAP team",
"license": "MIT"
}

1
packages/contract.cm/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
deploy/calls.yaml

View File

@ -0,0 +1,12 @@
# this is the contract id
__CWEB_CONTRACT_SELF_REFERENCE__:
# out contract does not take any arguments, so we pass an empty object
args:
- "CREATE_ORDER"
- "0x000000000000000000000000000000000000000000000001236efcbcbb340000"
- "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000"
- "0x9A4250b8c30Ca3cC5Dc33Ddbe30f71509a2E60a5"
- "0x00000000000000000000000000000000000000000000000002ea11e32ad50000"
- "0x00000000000000000000000000000000000000000000000000000000000186a0"
cweb_provided: "0x00000000000000000000000000000000000000000000000126590e9fe60a86a0"
auth: true

View File

@ -0,0 +1,39 @@
{
"name": "dex-app.cm",
"version": "0.0.97+test",
"type": "module",
"description": "dex-app.cm Contract to create an offer to give cweb in exchange for an specific l1-token",
"homepage": "https://git.coinhq.store/acme/cwap/",
"repository": {
"type": "git",
"url": "git+https://git.coinhq.store/acme/cwap.git"
},
"scripts": {
"build": "yarn build:files && yarn pack:all",
"build:files": "yarn clean && yarn g:tsc -p tsconfig.build.json && NODE_ENV=production yarn g:cweb-tool build-cm .",
"start": "node src/offchain/index.js",
"test": "yarn g:vitest run --pool=forks",
"test:prepare": "mkdir -p tests_data && cp ../../.cweb_tool/simulation/unknown.json tests_data/state.json && cp ../../.dapp-ecosystem-lock-test.yaml tests_data/index.yaml",
"test:watch": "yarn g:vitest",
"test:coverage": "yarn g:vitest run --coverage",
"pack:relink": "cd $INIT_CWD && node scripts/package-relink.js",
"pack:all": "yarn pack:cweb && yarn pack:relink && yarn pack:yarn && yarn pack:relink",
"pack:cweb": "yarn g:cweb-tool pack . dist/out ../../.cweb-config/cweb-pack.yaml -c ../../.cweb-config/config.yaml --profile $REGISTRATION_PROFILE",
"pack:yarn": "cd dist/out && touch yarn.lock && yarn pack -o my-contract-module.tgz",
"clean": "rm -rf cweb_dist dist .calls.yaml",
"typecheck": "yarn g:tsc --noEmit",
"dev": "yarn g:tsc -p tsconfig.dev.json --watch",
"lint": "yarn g:lint ."
},
"dependencies": {
"@coinweb/contract-kit": "0.2.6",
"@coinweb/self-register": "0.1.3",
"@noble/hashes": "1.4.0",
"bech32": "2.0.0",
"bs58": "6.0.0"
},
"main": "cweb_dist/offchain/index.js",
"engines": {
"cweb_interpreter": "a344c6003922f9e44385f6e8234a7d2567d9a676b14330ad3b42cbd1948a92bf"
}
}

View File

@ -0,0 +1,33 @@
import { readFileSync, writeFileSync } from 'fs';
import { resolve } from 'path';
import { fileURLToPath } from 'url';
const workspaceLink = 'workspaces:*';
const __dirname = fileURLToPath(new URL('.', import.meta.url));
// Update target package.json
const targetPath = resolve(__dirname, '../dist/out/package.json');
const targetPackage = JSON.parse(readFileSync(targetPath, 'utf8'));
// Process all cm- dependencies
Object.keys(targetPackage.dependencies).forEach((dependency) => {
if (dependency.startsWith('cwap-cm-')) {
// Read source version from the corresponding package
const sourcePath = resolve(__dirname, `../../${dependency}/package.json`);
try {
const sourcePackage = JSON.parse(readFileSync(sourcePath, 'utf8'));
const sourceVersion = sourcePackage.version;
if (targetPackage.dependencies[dependency] === workspaceLink) {
targetPackage.dependencies[dependency] = sourceVersion;
} else {
targetPackage.dependencies[dependency] = workspaceLink;
}
} catch (err) {
console.warn(`Warning: Could not read package.json for ${dependency} at ${sourcePath}: ${err.message}`);
}
}
});
// Write back the updated package.json
writeFileSync(targetPath, JSON.stringify(targetPackage, null, 2));

View File

@ -0,0 +1,115 @@
import { ClaimKey, User } from '@coinweb/contract-kit';
import { Client } from 'cwap-cm-lib/offchain';
import {
createActiveOrderIndexFirstPart,
createBestByQuoteActiveIndexFirstPart,
createBestByQuoteIndexFirstPart,
createDateIndexFirstPart,
createL1TxInfoFirstPart,
createOrderStateKey,
createOwnerlessIndexFirstPart,
createUniquenessFirstPart,
createUserIndexFirstPart,
} from './shared/keys';
import { BtcChainData, L1TxInfoData, OrderStateClaimBody } from './shared/types';
import { OrderData } from './types';
export const getActiveOrderIds = async (client: Client): Promise<string[]> => {
const claimsResponse = await client.fetchClaims(createActiveOrderIndexFirstPart(), null);
return claimsResponse.map(({ content }) => ((content.key as ClaimKey).second_part as [number, string])[1]);
};
export const getBestOrderIds = async (client: Client): Promise<string[]> => {
const claimsResponse = await client.fetchClaims(createBestByQuoteIndexFirstPart(), null);
return claimsResponse.map(({ content }) => ((content.key as ClaimKey).second_part as [number, string])[1]);
};
export const getBestActiveOrderIds = async (client: Client): Promise<string[]> => {
const claimsResponse = await client.fetchClaims(createBestByQuoteActiveIndexFirstPart(), null);
return claimsResponse.map(({ content }) => ((content.key as ClaimKey).second_part as [number, string])[1]);
};
export const getLastOrderIds = async (client: Client): Promise<string[]> => {
const claimsResponse = await client.fetchClaims(createDateIndexFirstPart(), null);
return claimsResponse.map(({ content }) => ((content.key as ClaimKey).second_part as [number, string])[1]);
};
export const getUserOrderIds = async (client: Client, user: User): Promise<string[]> => {
const claimsResponse = await client.fetchClaims(createUserIndexFirstPart(user), null);
return claimsResponse.map(({ content }) => ((content.key as ClaimKey).second_part as [number, string])[1]);
};
export const getOwnerlessOrderIds = async (client: Client): Promise<string[]> => {
const claimsResponse = await client.fetchClaims(createOwnerlessIndexFirstPart(), null);
return claimsResponse.map(({ content }) => ((content.key as ClaimKey).second_part as [string])[0]);
};
export const getUtxosInUse = async (client: Client): Promise<Pick<BtcChainData, 'l1TxId' | 'vout'>[]> => {
const claimsResponse = await client.fetchClaims(createUniquenessFirstPart(), null);
return claimsResponse.map(({ content: { key } }) => {
const [l1TxId, vout] = (key as ClaimKey).second_part as [BtcChainData['l1TxId'], BtcChainData['vout']];
return {
l1TxId,
vout,
};
});
};
export const getOrderById = async (client: Client, id: string) => {
const key = createOrderStateKey(id);
const claimResponse = (await client.fetchClaims(key.first_part, key.second_part))[0];
if (!claimResponse) {
throw new Error('Order not found');
}
const data = claimResponse.content.body as OrderStateClaimBody;
return {
id,
baseAmount: BigInt(data.baseAmount),
l1Amount: BigInt(data.l1Amount),
minL1Amount: BigInt(data.minL1Amount),
recipient: data.recipient,
createdAt: data.createdAt,
activityStatus: data.activityStatus,
paymentStatus: data.paymentStatus,
funds: BigInt(data.funds),
chainData: data.chainData,
txId: data.txId,
error: data.error,
expirationDate: data.expirationDate,
history: data.history,
isOwnerless: data.isOwnerless,
} satisfies OrderData;
};
export const getOwnerlessOrders = async (client: Client) => {
const ids = await getOwnerlessOrderIds(client);
try {
const orders = await Promise.all(ids.map((id) => getOrderById(client, id)));
return orders;
} catch (e) {
console.error({ e });
return [];
}
};
export const getL1TxInfo = async (client: Client, user: User): Promise<L1TxInfoData[]> => {
const claimsResponse = await client.fetchClaims(createL1TxInfoFirstPart(user), null);
return claimsResponse.map((claim) => claim.content.body as L1TxInfoData);
};

View File

@ -0,0 +1,6 @@
export * from './api';
export * from './uiCommands';
export * from './types';
export * from './shared';
export * from './createL1TxData';
export * from './reexport';

View File

@ -0,0 +1,95 @@
import { BtcNetworkParams, CreateOrderBaseParams } from './types';
export enum Key {
STATE = 'STATE',
FUNDS = 'FUNDS',
USER_INDEX = 'USER_INDEX',
DATE_INDEX = 'DATE_INDEX',
BEST_BY_QUOTE_INDEX = 'BEST_BY_QUOTE_INDEX',
ACTIVE_INDEX = 'ACTIVE_INDEX',
OWNERLESS_INDEX = 'OWNERLESS_INDEX',
CLOSED_INDEX = 'CLOSED_INDEX',
ERROR_INDEX = 'ERROR_INDEX',
UNIQUENESS_CHECK = 'UNIQUENESS_CHECK',
CONTRACT_OWNER = 'CONTRACT_OWNER',
L1_TX_INFO = 'L1_TX_INFO',
INCREMENT_INDEX = 'INCREMENT_INDEX',
}
export enum ACTIVITY_STATUS {
ACTIVE = 'ACTIVE',
COMPLETED = 'COMPLETED',
CANCELLING = 'CANCELLING',
CANCELLED = 'CANCELLED',
EXPIRED = 'EXPIRED',
ERROR = 'ERROR',
}
export enum PAYMENT_STATUS {
PAYABLE = 'PAYABLE',
NOT_PAYABLE = 'NOT_PAYABLE',
PAID = 'PAID',
}
export enum PUBLIC_METHODS {
CREATE_ORDER = '0x01',
CANCEL_ORDER = '0x02',
CHANGE_CONTRACT_OWNER = '0x03',
}
export const FEE = {
CREATE_ORDER: 2000000n,
CANCEL_ORDER: 1000000n,
};
export enum CallType {
Accept = 128,
TransferWithSelfTokenFallback = 129,
TransferWithQuoteTokenFallback = 130,
}
export enum Encoding {
Hex = 128,
Base58 = 129,
Bech32 = 130,
Bech32m = 131,
}
export enum L1Network {}
export const BTC_MAIN_NET = {
bech32: 'bc',
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80,
};
export const BTC_TEST_NET: BtcNetworkParams = {
bech32: 'tb',
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0xef,
};
export const BtcShardNetwork = {
btc: BTC_MAIN_NET,
tbtc: BTC_TEST_NET,
} satisfies Record<'btc' | 'tbtc', BtcNetworkParams>;
export enum BtcNetworkCode {
btc = 128,
tbtc = 129,
}
export const BtcCodeNetwork = {
[BtcNetworkCode.btc]: BTC_MAIN_NET,
[BtcNetworkCode.tbtc]: BTC_TEST_NET,
};
export const OrderBatchFields = [
'l1Amount',
'l1Address',
'minL1Amount',
'baseAmount',
'chainData',
] as const satisfies (keyof CreateOrderBaseParams)[];

View File

@ -0,0 +1,5 @@
export * from './keys';
export * from './utils';
export * from './constants';
export * from './types';
export { parseL1TxData } from '../createL1TxData';

View File

@ -0,0 +1,115 @@
import type { ClaimKey, OrdJson, User } from '@coinweb/contract-kit';
import { Key } from './constants';
import { BtcChainData } from './types';
/* FirstPart */
export const createOrderStateFirstPart = () => [Key.STATE];
export const createOrderFundsFirstPart = () => [Key.FUNDS];
export const createDateIndexFirstPart = () => [Key.DATE_INDEX];
export const createBestByQuoteIndexFirstPart = () => [Key.BEST_BY_QUOTE_INDEX];
export const createActiveOrderIndexFirstPart = () => [Key.ACTIVE_INDEX];
export const createBestByQuoteActiveIndexFirstPart = () => [Key.BEST_BY_QUOTE_INDEX, Key.ACTIVE_INDEX];
export const createUserIndexFirstPart = (user: User) => [Key.USER_INDEX, user];
export const createClosedIndexFirstPart = () => [Key.CLOSED_INDEX];
export const createOwnerlessIndexFirstPart = () => [Key.OWNERLESS_INDEX];
export const createOwnerFirstPart = () => [Key.CONTRACT_OWNER];
export const createUniquenessFirstPart = () => [Key.UNIQUENESS_CHECK]; //TODO: Add second element as a type of uniqueness
export const createL1TxInfoFirstPart = (user: User | null) => [Key.L1_TX_INFO, user];
/* Key */
export const createOrderStateKey = (orderId: string) =>
({
first_part: createOrderStateFirstPart(),
second_part: [orderId],
}) satisfies ClaimKey;
export const createOrderFundsKey = (orderId: string) =>
({
first_part: createOrderFundsFirstPart(),
second_part: [orderId],
}) satisfies ClaimKey;
export const createDateIndexKey = (timestamp: number, orderId: string) =>
({
first_part: createDateIndexFirstPart(),
second_part: [Number.MAX_SAFE_INTEGER - timestamp, orderId],
}) satisfies ClaimKey;
export const createBestByQuoteIndexKey = (rate: bigint, orderId: string) =>
({
first_part: createBestByQuoteIndexFirstPart(),
second_part: [rate.toString(16), orderId],
}) satisfies ClaimKey;
export const createActiveOrderIndexKey = (timestamp: number, orderId: string) =>
({
first_part: createActiveOrderIndexFirstPart(),
second_part: [Number.MAX_SAFE_INTEGER - timestamp, orderId],
}) satisfies ClaimKey;
export const createBestByQuoteActiveIndexKey = (rate: bigint, orderId: string) =>
({
first_part: createBestByQuoteActiveIndexFirstPart(),
second_part: [rate.toString(16), orderId],
}) satisfies ClaimKey;
export const createUserIndexKey = (user: User, timestamp: number, orderId: string) =>
({
first_part: createUserIndexFirstPart(user),
second_part: [Number.MAX_SAFE_INTEGER - timestamp, orderId],
}) satisfies ClaimKey;
export const createClosedIndexKey = (orderId: string) =>
({
first_part: createClosedIndexFirstPart(),
second_part: [orderId],
}) satisfies ClaimKey;
export const createOwnerlessIndexKey = (orderId: string) =>
({
first_part: createOwnerlessIndexFirstPart(),
second_part: [orderId],
}) satisfies ClaimKey;
export const createOwnerKey = () =>
({
first_part: createOwnerFirstPart(),
second_part: [],
}) satisfies ClaimKey;
export const createUniquenessKey = (data: OrdJson) =>
({
first_part: createUniquenessFirstPart(),
second_part: data,
}) satisfies ClaimKey;
export const createBtcUtxoUniquenessKey = (data: BtcChainData) =>
({
first_part: createUniquenessFirstPart(),
second_part: [data.l1TxId, data.vout],
}) satisfies ClaimKey;
export const createL1TxKey = (timestamp: number, uniqueId: string, user: User | null) =>
({
first_part: createL1TxInfoFirstPart(user),
second_part: [Number.MAX_SAFE_INTEGER - timestamp, uniqueId],
}) satisfies ClaimKey;
export const createIdIncrementIndexKey = () =>
({
first_part: [Key.INCREMENT_INDEX],
second_part: [Key.INCREMENT_INDEX],
}) satisfies ClaimKey;

View File

@ -0,0 +1,124 @@
import type { HexString, User } from '@coinweb/contract-kit';
import { HistoryAccess } from 'cwap-cm-lib/history/shared';
import { HexBigInt, BigIntToHex, L1Types } from 'cwap-cm-lib/shared';
import { ACTIVITY_STATUS, PAYMENT_STATUS, CallType, BTC_MAIN_NET, OrderBatchFields } from './constants';
export type PubKey = string;
export type OrderStateClaimBody = {
recipient: string;
baseAmount: HexBigInt;
l1Amount: HexBigInt;
minL1Amount: HexBigInt;
createdAt: number;
expirationDate: number;
activityStatus: ACTIVITY_STATUS;
paymentStatus: PAYMENT_STATUS;
funds: HexBigInt;
chainData: ChainData;
txId: string;
error: string | null;
isOwnerless?: boolean;
history: HistoryAccess;
};
export type OrderFundsClaimBody = {
owner: User;
};
export type ChainData = unknown;
export type BtcChainData = {
l1TxId: string;
vout: number;
psbt: string;
};
export type L1TxInfoData = {
l1TxId: string;
recipientAddress: string;
backPayAddress: string;
amount: HexBigInt;
l2TxId: string;
};
type L1TxAcceptPayload = {
baseRecipient: HexString;
};
type L1TxTransferBasePayload = {
c2ContractId: HexString;
c2ContractMethod: HexString;
minL1Amount: HexBigInt;
promisedL1Amount: HexBigInt;
l1Recipient: HexString;
l1ChainType: L1Types;
};
type L1TxTransferWithSelfFallbackPayload = {
fallbackRecipient: string;
} & L1TxTransferBasePayload;
type L1TxTransferWithQuoteFallbackPayload = {
fallbackC1ContractId: HexString;
fallbackC1ContractMethod: HexString;
} & L1TxTransferBasePayload;
export type AcceptData = {
callType: CallType.Accept;
} & L1TxAcceptPayload;
export type TransferWithSelfFallbackData = {
callType: CallType.TransferWithSelfTokenFallback;
} & L1TxTransferWithSelfFallbackPayload;
export type TransferWithQuoteFallbackData = {
callType: CallType.TransferWithQuoteTokenFallback;
} & L1TxTransferWithQuoteFallbackPayload;
export type CreateOrderBaseParams = {
l1Amount: bigint;
l1Address: string;
minL1Amount?: bigint;
baseAmount?: bigint;
chainData?: ChainData;
};
export type CreateOrderEvmBaseParams = CreateOrderBaseParams;
export type CreateOrderBtcBaseParams = Omit<CreateOrderBaseParams, 'chainData'> & {
chainData: BtcChainData;
};
export type OrdersBatch<T extends CreateOrderBaseParams = CreateOrderBaseParams> = [
number,
Partial<T>,
Partial<T>[]?,
][];
export type EvmOrdersBatch = OrdersBatch<CreateOrderEvmBaseParams>;
export type BtcOrdersBatch = OrdersBatch<CreateOrderBtcBaseParams>;
export type SerializableOrderParams = BigIntToHex<CreateOrderBaseParams>;
type BatchFields = typeof OrderBatchFields;
export type SerializedOrderTemplate = {
[I in keyof BatchFields & `${number}`]: BatchFields[I] extends keyof CreateOrderBaseParams
? BigIntToHex<Required<CreateOrderBaseParams[BatchFields[I]]>> | null
: never;
};
export type SerializedOrderTune = {
[I in keyof BatchFields & `${number}`]?: BatchFields[I] extends keyof CreateOrderBaseParams
? BigIntToHex<CreateOrderBaseParams[BatchFields[I]]>
: never;
};
export type SerializedOrdersBatch = [OrdersBatch[number][0], SerializedOrderTemplate, SerializedOrderTune[]?][];
export type CreateOrderCallArgs = [orders: SerializedOrdersBatch];
export type CancelOrderArguments = [ids: string[]];
export type ChangeContractOwnerArguments = [newOwner: User];
export type BtcNetworkParams = typeof BTC_MAIN_NET;

View File

@ -0,0 +1,101 @@
import { HexBigInt, BigIntToHex, toHex32, toHex } from 'cwap-cm-lib/shared';
import { FEE, OrderBatchFields } from './constants';
import { OrdersBatch, SerializedOrdersBatch, CreateOrderBaseParams, SerializedOrderTemplate } from './types';
export const ordersBatchToList = (ordersBatch: OrdersBatch) => {
return ordersBatch
.map((orderSet) => {
const orders = Array(orderSet[0])
.fill(orderSet[1])
.map((order, i) => ({ ...order, ...orderSet[2]?.[i] }) as CreateOrderBaseParams);
return orders;
}, [])
.flat();
};
export const serializeOrdersBatch = (ordersBatch: OrdersBatch): SerializedOrdersBatch => {
return ordersBatch.map(([count, base, tunes]) => [
count,
[
base.l1Amount ? toHex32(base.l1Amount) : null,
base.l1Address ? base.l1Address : null,
base.minL1Amount ? toHex32(base.minL1Amount) : null,
base.baseAmount ? toHex32(base.baseAmount) : null,
base.chainData ? base.chainData : null,
],
tunes?.map((tune) =>
Object.fromEntries(
Object.entries(tune).map(([key, value]) => [
OrderBatchFields.findIndex((field) => field === key),
['baseAmount', 'l1Amount', 'minL1Amount'].includes(key) ? toHex(value as bigint) : value,
])
)
),
]);
};
export const deserializeBatchToList = (ordersBatch: SerializedOrdersBatch): CreateOrderBaseParams[] => {
return ordersBatch
.map((orderSet) => {
const orders = Array(orderSet[0])
.fill(
Object.fromEntries(
OrderBatchFields.map((field, i) => [
field,
orderSet[1][i as unknown as keyof SerializedOrderTemplate],
]).filter(([_, value]) => value !== null)
)
)
.map((order: Partial<BigIntToHex<CreateOrderBaseParams>>, i) => ({
...order,
...(orderSet[2]?.[i] &&
Object.fromEntries(
Object.entries(orderSet[2][i]).map(([key, value]) => [OrderBatchFields[Number(key)], value])
)),
}))
.map((order) =>
Object.fromEntries(
Object.entries(order).map(([key, value]) => {
return [
key,
['baseAmount', 'l1Amount', 'minL1Amount'].includes(key) && value ? BigInt(value as HexBigInt) : value,
];
})
)
);
return orders;
}, [])
.flat() as CreateOrderBaseParams[];
};
export const calculateOrdersListParams = (orders: CreateOrderBaseParams[]) => {
const ordersLength = BigInt(orders.length);
const { l1Amount, minL1Amount, definedBaseAmount, itemsWithUndefinedBaseAmount } = orders.reduce(
(result, order) => {
if (!order.l1Amount) {
throw new Error('creteNewOrderUiCommand: wrong arguments received');
}
return {
l1Amount: result.l1Amount + BigInt(order.l1Amount),
minL1Amount: result.minL1Amount + BigInt(order.minL1Amount ?? 0),
definedBaseAmount: result.definedBaseAmount + BigInt(order.baseAmount ?? 0),
itemsWithUndefinedBaseAmount: result.itemsWithUndefinedBaseAmount + (order.baseAmount ? 0n : 1n),
};
},
{ l1Amount: 0n, minL1Amount: 0n, definedBaseAmount: 0n, itemsWithUndefinedBaseAmount: 0n }
);
return {
l1Amount,
minL1Amount,
definedBaseAmount,
itemsWithUndefinedBaseAmount,
fee: FEE.CREATE_ORDER * ordersLength,
isBatch: ordersLength > 1n,
ordersLength,
};
};

View File

@ -0,0 +1,52 @@
import {
BtcOrdersBatch,
ChainData,
CreateOrderBaseParams,
CreateOrderBtcBaseParams,
CreateOrderEvmBaseParams,
EvmOrdersBatch,
OrdersBatch,
OrderStateClaimBody,
} from './shared';
export type CreateOrderData<T extends CreateOrderBaseParams = CreateOrderBaseParams> = T & {
contractId: string;
contractOwnerFee: bigint;
accessId?: string;
};
export type CreateOrderBtcData = CreateOrderData<CreateOrderBtcBaseParams>;
export type CreateOrderEvmData = CreateOrderData<CreateOrderEvmBaseParams>;
export type CreateOrdersData<T extends OrdersBatch = OrdersBatch> = {
contractId: string;
orders: T;
contractOwnerFee: bigint;
accessId?: string;
};
export type CreateOrdersBtcData = CreateOrdersData<BtcOrdersBatch>;
export type CreateOrdersEvmData = CreateOrdersData<EvmOrdersBatch>;
export type CancelOrderData = {
contractId: string;
orderId: string;
accessId?: string;
};
export type CancelOrdersData = {
contractId: string;
orderIds: string[];
accessId?: string;
};
type OrderDataTransformed = {
id: string;
baseAmount: bigint;
l1Amount: bigint;
minL1Amount: bigint;
funds: bigint;
chainData?: ChainData;
};
export type OrderData = OrderDataTransformed & Omit<OrderStateClaimBody, keyof OrderDataTransformed>;

View File

@ -0,0 +1,130 @@
import { withMetadata } from 'cwap-cm-lib/history/offchain';
import { HISTORY_ACCESS_FEE } from 'cwap-cm-lib/history/shared';
import { constructCall, constructUiCommand } from 'cwap-cm-lib/offchain';
import { FEE, serializeOrdersBatch, PUBLIC_METHODS, ordersBatchToList, calculateOrdersListParams } from './shared';
import {
CancelOrdersData,
CreateOrdersBtcData,
CreateOrdersEvmData,
CreateOrdersData,
CancelOrderData,
CreateOrderBtcData,
CreateOrderEvmData,
} from './types';
const constructCreateOrdersCall = ({ contractId, accessId, orders, contractOwnerFee }: CreateOrdersData) => {
const { l1Amount, minL1Amount, definedBaseAmount, fee } = calculateOrdersListParams(ordersBatchToList(orders));
if (l1Amount < minL1Amount) {
throw new Error('creteNewOrderUiCommand: l1Amount is less than minimum value');
}
return constructCall(
contractId,
PUBLIC_METHODS.CREATE_ORDER,
withMetadata([serializeOrdersBatch(orders)], accessId),
definedBaseAmount + fee + contractOwnerFee + (accessId ? HISTORY_ACCESS_FEE : 0n)
);
};
export const constructCreateBtcOrdersCall = (data: CreateOrdersBtcData) => {
return constructCreateOrdersCall(data);
};
export const constructCreateEvmOrdersCall = (data: CreateOrdersEvmData) => {
return constructCreateOrdersCall(data);
};
export const constructCancelOrdersCall = ({ contractId, orderIds, accessId }: CancelOrdersData) => {
return constructCall(
contractId,
PUBLIC_METHODS.CANCEL_ORDER,
withMetadata([orderIds], accessId),
FEE.CANCEL_ORDER * BigInt(orderIds.length) + (accessId ? HISTORY_ACCESS_FEE : 0n)
);
};
export const createOrderBtcUiCommand = ({
contractId,
baseAmount,
l1Amount,
minL1Amount,
l1Address,
chainData,
accessId,
contractOwnerFee,
}: CreateOrderBtcData) => {
if (!baseAmount) {
throw new Error('createOrderBtcUiCommand: baseAmount is not defined');
}
return constructUiCommand([
constructCreateOrdersCall({
contractId,
orders: [
[
1,
{
baseAmount,
l1Amount,
minL1Amount,
l1Address,
chainData,
},
],
],
accessId,
contractOwnerFee,
}),
]);
};
export const createOrderEvmUiCommand = ({
contractId,
baseAmount,
l1Amount,
minL1Amount,
l1Address,
accessId,
contractOwnerFee,
}: CreateOrderEvmData) => {
if (!baseAmount) {
throw new Error('createOrderEvmUiCommand: baseAmount is not defined');
}
return constructUiCommand([
constructCreateOrdersCall({
contractId,
orders: [
[
1,
{
baseAmount,
l1Amount,
minL1Amount,
l1Address,
},
],
],
accessId,
contractOwnerFee,
}),
]);
};
export const createOrdersBtcUiCommand = (data: CreateOrdersBtcData) => {
return constructUiCommand([constructCreateOrdersCall(data)]);
};
export const createOrdersEvmUiCommand = (data: CreateOrdersEvmData) => {
return constructUiCommand([constructCreateOrdersCall(data)]);
};
export const cancelOrderUiCommand = ({ contractId, orderId, accessId }: CancelOrderData) => {
return constructUiCommand([constructCancelOrdersCall({ contractId, orderIds: [orderId], accessId })]);
};
export const cancelOrdersUiCommand = (data: CancelOrdersData) => {
return constructUiCommand([constructCancelOrdersCall(data)]);
};

View File

@ -0,0 +1,8 @@
export const PRIVATE_METHODS = {
CREATE_ORDER: 'CREATE_ORDER_PRIVATE',
CREATE_ORDER_INDEXES: 'CREATE_ORDER_INDEXES_PRIVATE',
DEACTIVATE_ORDER: 'DEACTIVATE_ORDER_PRIVATE',
CLOSE_ORDER: 'CLOSE_ORDER_PRIVATE',
HANDLE_BLOCK_TRIGGERED: 'HANDLE_BLOCK_TRIGGERED_PRIVATE',
CHANGE_CONTRACT_OWNER: 'CHANGE_CONTRACT_OWNER_PRIVATE',
};

View File

@ -0,0 +1,56 @@
import {
ContractHandlers,
MethodCallback,
SELF_REGISTER_HANDLER_NAME,
addMethodHandler,
executeHandler,
selfCallWrapper,
} from '@coinweb/contract-kit';
import { selfRegisterHandler } from '@coinweb/self-register';
import { queue, withContractCallLogger } from 'cwap-cm-lib/onchain';
import { PUBLIC_METHODS } from '../offchain/shared';
import { PRIVATE_METHODS } from './constants';
import {
cancelOrderPublic,
changeContractOwner,
changeOwnerPublic,
closeOrder,
createOrderIndexes,
createOrder,
createOrderPublic,
deactivateOrder,
handleBlockTriggered,
} from './methods';
const addWrappers = (method: MethodCallback): MethodCallback => {
return selfCallWrapper(withContractCallLogger(method));
};
export const cwebMain = () => {
const module: ContractHandlers = { handlers: {} };
addMethodHandler(module, PUBLIC_METHODS.CREATE_ORDER, addWrappers(createOrderPublic));
addMethodHandler(module, PRIVATE_METHODS.CREATE_ORDER, addWrappers(createOrder));
addMethodHandler(module, PRIVATE_METHODS.CREATE_ORDER_INDEXES, addWrappers(createOrderIndexes));
addMethodHandler(module, PRIVATE_METHODS.HANDLE_BLOCK_TRIGGERED, addWrappers(handleBlockTriggered));
addMethodHandler(module, PUBLIC_METHODS.CANCEL_ORDER, addWrappers(cancelOrderPublic));
addMethodHandler(module, PRIVATE_METHODS.DEACTIVATE_ORDER, addWrappers(deactivateOrder));
addMethodHandler(module, PRIVATE_METHODS.CLOSE_ORDER, addWrappers(closeOrder));
addMethodHandler(module, PUBLIC_METHODS.CHANGE_CONTRACT_OWNER, addWrappers(changeOwnerPublic));
addMethodHandler(module, PRIVATE_METHODS.CHANGE_CONTRACT_OWNER, addWrappers(changeContractOwner));
addMethodHandler(module, SELF_REGISTER_HANDLER_NAME, selfRegisterHandler);
queue.applyQueue(module, [
PUBLIC_METHODS.CANCEL_ORDER,
PUBLIC_METHODS.CHANGE_CONTRACT_OWNER,
PUBLIC_METHODS.CREATE_ORDER,
]);
executeHandler(module);
};

View File

@ -0,0 +1 @@
export * from './contract';

View File

@ -0,0 +1,64 @@
import { HexString, Shard, User } from '@coinweb/contract-kit';
import { Logs } from 'cwap-cm-lib/onchain';
import { HexBigInt, L1Types } from 'cwap-cm-lib/shared';
import { AcceptData, TransferWithSelfFallbackData, TransferWithQuoteFallbackData } from '../offchain/shared';
export type EvmEventClaimBody = {
data: string;
l1_txid: string;
};
export type BtcEventClaimBody = {
UtxoBased: {
vout: {
scriptPubKey: {
asm: string;
};
}[];
txid: string;
};
};
export type CallContractData = {
c2Contract: string;
c2MethodName: string;
c2Args: [...args: unknown[]];
};
export type L1EventData = {
recipient: HexBigInt;
paidAmount: HexBigInt;
l1TxId: string;
} & (AcceptData | TransferWithSelfFallbackData | TransferWithQuoteFallbackData);
export type InstanceParameters = {
l1_type: L1Types;
l1_contract_address?: string;
l1_transfer_event_signature?: string;
shard: Shard;
owner: User;
logs?: Logs[];
owner_min_fee?: HexString;
owner_percentage_fee?: number;
order_life_time: number;
close_order_timeout: number;
jump_contract_id: string;
jump_contract_method: string;
jump_contract_jumps: number;
};
export type InstanceParametersForEvm = {
l1_type: L1Types.Evm;
l1_contract_address: string;
l1_transfer_event_signature: string;
} & Omit<InstanceParameters, 'l1_type' | 'l1_contract_address' | 'l1_transfer_event_signature'>;
export type InstanceParametersForBtc = {
l1_type: L1Types.Btc;
} & Omit<InstanceParameters, 'l1_type' | 'l1_contract_address' | 'l1_transfer_event_signature'>;
export type OwnerClaimBody = {
owner: User;
updatedAt: number;
};

View File

@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"declaration": true,
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["./src/**/*.ts"],
"exclude": ["**/__tests__", "**/__mocks__", "*.tests.ts"]
}

View File

@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"declaration": true,
"rootDir": "./src",
"outDir": "./cweb_dist/"
},
"exclude": ["**/__tests__", "**/__mocks__", "vitest.config.ts", "tsconfig.dev.json", "*.tests.ts"]
}

View File

@ -0,0 +1,13 @@
{
"compilerOptions": {
"strict": true,
"target": "ESNEXT",
"module": "ESNEXT",
"moduleResolution": "Bundler",
"rootDir": ".",
"resolveJsonModule": true,
"esModuleInterop": true,
"types": ["vitest/globals"]
},
"include": ["src/**/*.ts", "vitest.*.ts", "__tests__", "../cwap-cm-lib/src/onchain/features/logger.ts"]
}

View File

@ -0,0 +1,30 @@
{
"name": "cwait",
"version": "0.0.17+test",
"type": "module",
"homepage": "https://git.coinhq.store/acme/cwap/",
"repository": {
"type": "git",
"url": "git+https://git.coinhq.store/acme/cwap.git"
},
"scripts": {
"build": "yarn g:tsc -p tsconfig.build.json",
"dev": "yarn g:tsc -p tsconfig.build.json --watch",
"lint": "yarn g:lint .",
"publish:lib": "node scripts/publish.js"
},
"dependencies": {
"@coinweb/contract-kit": "0.2.5",
"@coinweb/self-register": "0.1.3",
"lib": "workspaces:*"
},
"files": [
"dist"
],
"exports": {
".": {
"types": "./dist/onchain/index.d.ts",
"import": "./dist/onchain/index.js"
}
}
}

View File

@ -0,0 +1,61 @@
import { execSync } from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
const level = process.argv[2] || '--patch';
// Read the current version from package.json
const packageJsonPath = path.join(process.cwd(), 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
const currentVersion = packageJson.version;
let [major, minor, patchWithSuffix] = currentVersion.split('.');
let [patch, ...suffixParts] = patchWithSuffix.match(/(\d+)([^\d].*)?/).slice(1);
const suffix = suffixParts.join('') || '';
switch (level) {
case '--patch':
patch = Number(patch) + 1;
break;
case '--minor':
minor = Number(minor) + 1;
patch = 0;
break;
case '--major':
major = Number(major) + 1;
minor = 0;
patch = 0;
break;
default:
throw new Error(`Invalid level: ${level}`);
}
try {
const newVersion = `${[major, minor, patch].join('.')}${suffix}`;
packageJson.version = newVersion;
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
// Login to npm
if (process.env.NPM_USERNAME && process.env.NPM_PASSWORD) {
execSync(
`{ echo ${process.env.NPM_USERNAME}; sleep 1; echo ${process.env.NPM_PASSWORD}; } | yarn npm login --scope=coinweb`,
{ stdio: 'inherit' }
);
} else {
throw new Error('NPM_USERNAME and NPM_PASSWORD are not set');
}
// Publish the package to npm with the hash-tagged version
execSync(`npm publish`, { stdio: 'inherit' });
// biome-ignore lint/suspicious/noConsoleLog: cli tool
console.log(`Package published with version: ${newVersion}`);
} catch (error) {
console.error('Failed to publish package:');
console.error(error.message);
// RESTORE the original version in package.json
packageJson.version = currentVersion;
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
}

View File

@ -0,0 +1,29 @@
import { constructContractIssuer, Context, extractUser, getAuthenticated, getContractId } from '@coinweb/contract-kit';
let rawContext: Context | null = null;
export const setContext = (ctx: Context) => {
rawContext = ctx;
};
export const getContext = () => rawContext;
const useContext = <T>(cb: (ctx: Context) => T) => {
if (!rawContext) {
throw new Error('Context not set');
}
return cb(rawContext);
};
export const context = {
get issuer() {
return useContext((ctx) => constructContractIssuer(getContractId(ctx.tx)));
},
get authenticated() {
return useContext((ctx) => getAuthenticated(ctx.tx));
},
get user() {
return useContext((ctx) => extractUser(getAuthenticated(ctx.tx)));
},
};

View File

@ -0,0 +1 @@
export * from './context';

View File

View File

@ -0,0 +1,13 @@
import { PreparedOperation } from '@coinweb/contract-kit';
const awaitedOps: PreparedOperation[] = [];
export const pushAwaitedOp = (op: PreparedOperation | PreparedOperation[]) => {
if (Array.isArray(op)) {
awaitedOps.push(...op);
} else {
awaitedOps.push(op);
}
};
export const getAwaitedOps = () => awaitedOps;

View File

@ -0,0 +1,5 @@
export const blockOp = () => {
return new Promise<void>((resolve) => {
resolve();
});
};

View File

@ -0,0 +1,3 @@
export * from './block';
export * from './store';
export * from './take';

View File

@ -0,0 +1,27 @@
import { Claim, ClaimKey, constructRead, extractRead, isResolvedRead } from '@coinweb/contract-kit';
import { TypedClaim } from '../../types';
import { context } from '../context';
import { signal } from '../signal';
import { pushAwaitedOp } from './awaited';
import { shiftResolvedOp } from './resolved';
export const readOp = <TClaim extends Claim = TypedClaim>(key: ClaimKey) => {
const { op, isOp } = shiftResolvedOp();
if (!isOp) {
pushAwaitedOp(constructRead(context.issuer, key));
} else if (op && !isResolvedRead(op)) {
throw new Error('Read operation not found');
}
return new Promise<TClaim | null>((resolve, reject) => {
if (isOp) {
const claim = op && ((extractRead(op)?.[0] ?? null) as TClaim | null);
resolve(claim);
} else {
reject(signal);
}
});
};

View File

@ -0,0 +1,25 @@
import { ResolvedOperation } from '@coinweb/contract-kit';
const resolvedOps: ResolvedOperation[] = [];
export const pushResolvedOp = (op: ResolvedOperation | ResolvedOperation[]) => {
if (Array.isArray(op)) {
resolvedOps.push(...op);
} else {
resolvedOps.push(op);
}
};
export const shiftResolvedOp = () =>
({
isOp: resolvedOps.length > 0,
op: resolvedOps.shift(),
}) as
| {
isOp: true;
op: ResolvedOperation | null;
}
| {
isOp: false;
op: undefined;
};

View File

@ -0,0 +1,31 @@
import { Claim, constructStore, isResolvedStore } from '@coinweb/contract-kit';
import { extractStore } from '@coinweb/contract-kit/dist/types/operations/store';
import { signal } from '../signal';
import { pushAwaitedOp } from './awaited';
import { shiftResolvedOp } from './resolved';
export const storeOp = (claim: Claim) => {
const { op, isOp } = shiftResolvedOp();
if (!isOp) {
pushAwaitedOp(constructStore(claim));
} else if (op && !isResolvedStore(op)) {
throw new Error('Store operation not found');
}
const result = op && extractStore(op);
if (!result) {
throw new Error('Wrong store operation');
}
return new Promise<Claim>((resolve, reject) => {
if (isOp) {
resolve(result);
} else {
reject(signal);
}
});
};

View File

@ -0,0 +1,26 @@
import { constructTake, extractTake, isResolvedTake, Claim, ClaimKey } from '@coinweb/contract-kit';
import { TypedClaim } from '../../types';
import { signal } from '../signal';
import { pushAwaitedOp } from './awaited';
import { shiftResolvedOp } from './resolved';
export const takeOp = <TClaim extends Claim = TypedClaim>(key: ClaimKey) => {
const { op, isOp } = shiftResolvedOp();
if (!isOp) {
pushAwaitedOp(constructTake(key));
} else if (op && !isResolvedTake(op)) {
throw new Error('Take operation not found');
}
return new Promise<TClaim | null>((resolve, reject) => {
if (isOp) {
const claim = op && extractTake(op);
resolve(claim as TClaim | null);
} else {
reject(signal);
}
});
};

View File

@ -0,0 +1 @@
export const signal = Symbol('signal');

View File

@ -0,0 +1,9 @@
import { Claim, ClaimKey, OrdJson } from '@coinweb/contract-kit';
export type HexBigInt = `0x${string}`;
export type TypedClaim<TBody extends OrdJson = OrdJson, TKey extends ClaimKey = ClaimKey> = Claim & {
body: TBody;
fees_stored: HexBigInt;
key: TKey;
};

View File

@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"declaration": true,
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["./src/**/*.ts"],
"exclude": ["**/__tests__", "**/__mocks__", "*.tests.ts"]
}

View File

@ -0,0 +1,13 @@
{
"compilerOptions": {
"strict": true,
"target": "ESNEXT",
"module": "ESNEXT",
"moduleResolution": "Bundler",
"rootDir": ".",
"resolveJsonModule": true,
"esModuleInterop": true,
"types": ["vitest/globals"]
},
"include": ["**/*.ts", "vitest.*.ts", "__tests__", "scripts/publish.js"]
}

49
packages/lib/package.json Normal file
View File

@ -0,0 +1,49 @@
{
"name": "lib",
"version": "0.0.17+test",
"type": "module",
"homepage": "https://git.coinhq.store/acme/cwap/",
"repository": {
"type": "git",
"url": "git+https://git.coinhq.store/acme/cwap.git"
},
"scripts": {
"build": "yarn g:tsc -p tsconfig.build.json",
"dev": "yarn g:tsc -p tsconfig.build.json --watch",
"lint": "yarn g:lint .",
"publish:lib": "node scripts/publish.js"
},
"dependencies": {
"@coinweb/contract-kit": "0.2.5",
"@coinweb/self-register": "0.1.3"
},
"files": [
"dist"
],
"exports": {
"./offchain": {
"types": "./dist/offchain/index.d.ts",
"import": "./dist/offchain/index.js"
},
"./onchain": {
"types": "./dist/onchain/index.d.ts",
"import": "./dist/onchain/index.js"
},
"./shared": {
"types": "./dist/shared/index.d.ts",
"import": "./dist/shared/index.js"
},
"./history/offchain": {
"types": "./dist/module/history/offchain/index.d.ts",
"import": "./dist/module/history/offchain/index.js"
},
"./history/onchain": {
"types": "./dist/module/history/onchain/index.d.ts",
"import": "./dist/module/history/onchain/index.js"
},
"./history/shared": {
"types": "./dist/module/history/shared/index.d.ts",
"import": "./dist/module/history/shared/index.js"
}
}
}

View File

@ -0,0 +1,61 @@
import { execSync } from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
const level = process.argv[2] || '--patch';
// Read the current version from package.json
const packageJsonPath = path.join(process.cwd(), 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
const currentVersion = packageJson.version;
let [major, minor, patchWithSuffix] = currentVersion.split('.');
let [patch, ...suffixParts] = patchWithSuffix.match(/(\d+)([^\d].*)?/).slice(1);
const suffix = suffixParts.join('') || '';
switch (level) {
case '--patch':
patch = Number(patch) + 1;
break;
case '--minor':
minor = Number(minor) + 1;
patch = 0;
break;
case '--major':
major = Number(major) + 1;
minor = 0;
patch = 0;
break;
default:
throw new Error(`Invalid level: ${level}`);
}
try {
const newVersion = `${[major, minor, patch].join('.')}${suffix}`;
packageJson.version = newVersion;
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
// Login to npm
if (process.env.NPM_USERNAME && process.env.NPM_PASSWORD) {
execSync(
`{ echo ${process.env.NPM_USERNAME}; sleep 1; echo ${process.env.NPM_PASSWORD}; } | yarn npm login --scope=coinweb`,
{ stdio: 'inherit' }
);
} else {
throw new Error('NPM_USERNAME and NPM_PASSWORD are not set');
}
// Publish the package to npm with the hash-tagged version
execSync(`npm publish`, { stdio: 'inherit' });
// biome-ignore lint/suspicious/noConsoleLog: cli tool
console.log(`Package published with version: ${newVersion}`);
} catch (error) {
console.error('Failed to publish package:');
console.error(error.message);
// RESTORE the original version in package.json
packageJson.version = currentVersion;
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
}

View File

@ -0,0 +1,45 @@
import { ClaimKey } from '@coinweb/contract-kit';
import { Client } from '../../../offchain';
import {
createHistoryItemFirstPart,
creteHistoryAccessKey,
HistoryAccess,
HistoryAccessClaimBody,
HistoryItemClaimBody,
} from '../shared';
import { HistoryData } from './types';
export const getHistoryByHistoryAccess = async (client: Client, access: HistoryAccess): Promise<HistoryData[]> => {
const range =
access.timestamp === undefined
? undefined
: {
start: null,
end: [Number.MAX_SAFE_INTEGER - access.timestamp + 1, Number.MAX_SAFE_INTEGER, '~'],
};
const claimsResponse = await client.fetchClaims(createHistoryItemFirstPart(access.historyId), null, range);
return claimsResponse.map((claim) => {
const keySecondPart = (claim.content.key as ClaimKey).second_part as [number, number];
return {
...(claim.content.body as HistoryItemClaimBody),
timestamp: Number.MAX_SAFE_INTEGER - keySecondPart[0],
order: keySecondPart[1],
access,
};
});
};
export const getHistoryAccess = async (client: Client, uniqueId: string): Promise<HistoryAccess | undefined> => {
const key = creteHistoryAccessKey(uniqueId);
const access = (await client.fetchClaims(key.first_part, key.second_part))[0]?.content.body as
| HistoryAccessClaimBody
| undefined;
return access;
};

View File

@ -0,0 +1,3 @@
export * from './types';
export * from './api';
export * from './uiCommands';

View File

@ -0,0 +1,5 @@
import { ContractCallMetadataInterface, HistoryAccess, HistoryItemClaimBody } from '../shared';
export type ArgsWithMetadata<Args extends unknown[]> = [...Args, metadata?: ContractCallMetadataInterface];
export type HistoryData = HistoryItemClaimBody & { timestamp: number; order: number; access: HistoryAccess };

View File

@ -0,0 +1,14 @@
import { constructMetadata } from '../shared';
import { ArgsWithMetadata } from './types';
export const withMetadata = <TArgs extends unknown[]>(
args: TArgs,
accessId?: string | null
): ArgsWithMetadata<TArgs> => {
if (accessId) {
args.push(constructMetadata({ accessId }));
}
return args as unknown as ArgsWithMetadata<TArgs>;
};

View File

@ -0,0 +1,16 @@
import { Claim, constructClaim } from '@coinweb/contract-kit';
import { toHex32 } from '../../../../shared';
import { creteHistoryAccessKey, HistoryAccess } from '../../shared';
export const createHistoryAccessClaim = ({
id,
historyId,
timestamp,
}: {
id: string;
historyId: string;
timestamp?: number;
}): Claim => {
return constructClaim(creteHistoryAccessKey(id), { historyId, timestamp } satisfies HistoryAccess, toHex32(0));
};

View File

@ -0,0 +1,25 @@
import { Claim, constructClaim } from '@coinweb/contract-kit';
import { getContext, getTime } from '../../../../onchain';
import { toHex } from '../../../../shared';
import { createHistoryItemKey, HistoryItem, HistoryItemClaimBody } from '../../shared';
export const createHistoryClaim = ({
uniqueId,
historyId,
historyItem,
order,
}: {
uniqueId: string;
historyId: string;
historyItem: HistoryItem;
order: number;
}): Claim => {
const txId = getContext().call.txid;
return constructClaim(
createHistoryItemKey(historyId, getTime(), uniqueId, order),
{ ...historyItem, txId } satisfies HistoryItemClaimBody,
toHex(0)
);
};

View File

@ -0,0 +1,2 @@
export * from './historyAccess';
export * from './historyItem';

View File

@ -0,0 +1,31 @@
import { constructStore } from '@coinweb/contract-kit';
import { getTime } from '../../../../onchain';
import { createHistoryAccessClaim } from '../claims';
import { getMetadata } from '../metadata/metadata';
import { forceHistoryId } from './forceHistoryId';
export const constructCurrentHistoryAccess = (options?: { historyId?: string }) => {
const { historyId: providedHistoryId } = options || {};
const timestamp = getTime();
const id = getMetadata()?.accessId;
if (!id) {
return [];
}
const historyId = providedHistoryId ?? forceHistoryId();
return [
constructStore(
createHistoryAccessClaim({
id,
timestamp,
historyId,
})
),
];
};

View File

@ -0,0 +1,52 @@
import { constructStore } from '@coinweb/contract-kit';
import { getContext } from '../../../../onchain';
import { HistoryItem } from '../../shared';
import { createHistoryClaim } from '../claims';
import { getMetadata, setSetMetadata } from '../metadata/metadata';
import { updateMetadata } from '../metadata/updateMetadata';
import { forceHistoryId } from './forceHistoryId';
export const constructHistoryItem = ({
historyItem,
historyId: providedHistoryId,
}: {
historyId?: string;
historyItem: HistoryItem;
}) => {
const metadata = getMetadata();
const uniqueId = getContext().call.txid.slice(0, 16);
const order = metadata?.historyOrder ?? 0;
const historyId = providedHistoryId ?? forceHistoryId();
if (historyId !== providedHistoryId) {
if (metadata?.historyLink) {
const externalLink = metadata.historyLink;
historyItem.links = [...(historyItem.links ?? []), externalLink];
setSetMetadata({
...metadata,
historyLink: null,
});
}
}
if (!historyId) {
return [];
}
const historyClaim = createHistoryClaim({
historyId,
historyItem: { ...historyItem, links: historyItem.links ?? null },
uniqueId,
order,
});
updateMetadata({ historyOrder: order + 1 });
return [constructStore(historyClaim)];
};

View File

@ -0,0 +1,28 @@
import { constructStore } from '@coinweb/contract-kit';
import { getTime } from '../../../../onchain';
import { createHistoryAccessClaim } from '../claims';
import { forceHistoryId } from './forceHistoryId';
export const constructNewHistoryAccess = ({
accessId,
historyId: providedHistoryId,
}: {
accessId: string;
historyId?: string;
}) => {
const timestamp = getTime();
const historyId = providedHistoryId ?? forceHistoryId();
return [
constructStore(
createHistoryAccessClaim({
id: accessId,
timestamp,
historyId,
})
),
];
};

View File

@ -0,0 +1,15 @@
import { getTime } from '../../../../onchain';
import { HISTORY_CODES, HistoryLink } from '../../shared';
import { forceHistoryId } from './forceHistoryId';
export const createLinkToCurrentHistory = ({ code }: { code: HISTORY_CODES }): HistoryLink => {
const historyId = forceHistoryId();
const timestamp = getTime();
return {
historyId,
timestamp,
code,
};
};

View File

@ -0,0 +1,12 @@
import { getTime } from '../../../../onchain';
import { HISTORY_CODES, HistoryLink } from '../../shared';
export const createLinkToHistory = ({ code, historyId }: { code: HISTORY_CODES; historyId: string }): HistoryLink => {
const timestamp = getTime();
return {
historyId,
timestamp,
code,
};
};

View File

@ -0,0 +1,21 @@
import { getTime } from '../../../../onchain';
import { HistoryAccess } from '../../shared';
import { forceHistoryId } from './forceHistoryId';
import { getNewHistoryId } from './getNewHistoryId';
export const forceAccessToHistory = ({
historyId: providedHistoryId,
forceNew,
}: {
historyId?: string;
forceNew?: boolean;
} = {}): HistoryAccess => {
const historyId = forceNew ? getNewHistoryId() : providedHistoryId || forceHistoryId();
const timestamp = getTime();
return {
historyId,
timestamp,
};
};

View File

@ -0,0 +1,17 @@
import { getMetadata } from '../metadata/metadata';
import { updateMetadata } from '../metadata/updateMetadata';
import { getNewHistoryId } from './getNewHistoryId';
export const forceHistoryId = () => {
const trackingId = getMetadata()?.trackingId;
if (!trackingId) {
const newHistoryId = getNewHistoryId();
updateMetadata({ trackingId: newHistoryId });
return newHistoryId;
}
return trackingId;
};

View File

@ -0,0 +1,12 @@
import { getContext } from '../../../../onchain';
let localTrackingId: string | null = null;
let localTrackingDerivation = 0;
export const getNewHistoryId = () => {
if (!localTrackingId) {
localTrackingId = getContext().call.txid.slice(0, 16);
}
return `${localTrackingId}${localTrackingDerivation++}`;
};

View File

@ -0,0 +1,8 @@
export * from './constructCurrentHistoryAccess';
export * from './constructHistoryItem';
export * from './constructNewHistoryAccess';
export * from './createLinkToCurrentHistory';
export * from './createLinkToHistory';
export * from './forceAccessToHistory';
export * from './forceHistoryId';
export * from './getNewHistoryId';

View File

@ -0,0 +1,4 @@
export * from './claims';
export * from './features';
export * from './metadata';
export * from '../../../onchain/state';

View File

@ -0,0 +1,40 @@
import { ContractCallMetadataInterface, TrackingMetadataInterface } from '../../shared';
import { forceHistoryId } from '../features/forceHistoryId';
import { getMetadata } from './metadata';
export const createRawMetadata = (): ContractCallMetadataInterface | null => {
const metadata = getMetadata();
if (metadata?.trackingId) {
const rawMetadataWithTrackingId: TrackingMetadataInterface = {
_trackingId: metadata.trackingId,
};
if (metadata.historyOrder) {
rawMetadataWithTrackingId._historyOrder = metadata.historyOrder;
}
if (metadata.historyLink) {
rawMetadataWithTrackingId._historyLink = metadata.historyLink;
}
if (metadata.accessId) {
rawMetadataWithTrackingId._currentAccessId = metadata.accessId;
}
return {
_metadata: rawMetadataWithTrackingId,
};
}
if (metadata?.accessId) {
return {
_metadata: {
_trackingId: forceHistoryId(),
_currentAccessId: metadata.accessId,
},
};
}
return null;
};

View File

@ -0,0 +1,6 @@
export * from './createRawMetadata';
export * from './initMetadata';
export * from './isNewHistoryAccessId';
export * from './metadata';
export * from './updateMetadata';
export * from './validateMetadata';

View File

@ -0,0 +1,43 @@
import { Context, getMethodArguments } from '@coinweb/contract-kit';
import { setIsNewHistoryAccessId } from './isNewHistoryAccessId';
import { setSetMetadata } from './metadata';
import { validateMetadata } from './validateMetadata';
export const setMetadata = (context: Context) => {
const args = getMethodArguments(context);
const metadataArg = args.findLast(validateMetadata);
if (metadataArg) {
const historyOrder =
('_historyOrder' in metadataArg._metadata ? metadataArg._metadata._historyOrder : null) ?? null;
const historyLink = ('_historyLink' in metadataArg._metadata ? metadataArg._metadata._historyLink : null) ?? null;
const currentAccessId =
('_currentAccessId' in metadataArg._metadata ? metadataArg._metadata._currentAccessId : null) ?? null;
const newAccessId = ('_newAccessId' in metadataArg._metadata ? metadataArg._metadata._newAccessId : null) ?? null;
const trackingId = '_trackingId' in metadataArg._metadata ? metadataArg._metadata._trackingId : null;
if (trackingId) {
setSetMetadata({
trackingId,
historyOrder,
historyLink,
accessId: currentAccessId,
});
} else {
setSetMetadata({
trackingId: null,
historyOrder: null,
historyLink,
accessId: newAccessId,
});
}
if (newAccessId) {
setIsNewHistoryAccessId(true);
}
}
};

View File

@ -0,0 +1,7 @@
let isNewHistoryAccessId = false;
export const setIsNewHistoryAccessId = (newIsNewHistoryAccessId: boolean) => {
isNewHistoryAccessId = newIsNewHistoryAccessId;
};
export const checkIsNewHistoryAccessId = () => isNewHistoryAccessId;

View File

@ -0,0 +1,9 @@
import { ContractCallMetadata } from '../../shared';
let metadata: ContractCallMetadata | null = null;
export const setSetMetadata = (newMetadata: ContractCallMetadata | null) => {
metadata = newMetadata;
};
export const getMetadata = () => metadata;

View File

@ -0,0 +1,18 @@
import { getMetadata, setSetMetadata } from './metadata';
export const updateMetadata = (newMetadata: { trackingId?: string; historyOrder?: number }) => {
const currentMetadata = getMetadata();
const trackingId = newMetadata.trackingId ?? currentMetadata?.trackingId;
if (!trackingId) {
return;
}
setSetMetadata({
trackingId,
historyOrder: newMetadata.historyOrder ?? currentMetadata?.historyOrder ?? null,
historyLink: currentMetadata?.historyLink ?? null,
accessId: currentMetadata?.accessId ?? null,
});
};

View File

@ -0,0 +1,15 @@
import { ContractCallMetadataInterface } from '../../shared';
export const validateMetadata = (maybeMetadata: unknown): maybeMetadata is ContractCallMetadataInterface => {
if (
maybeMetadata &&
typeof maybeMetadata === 'object' &&
'_metadata' in maybeMetadata &&
maybeMetadata._metadata &&
typeof maybeMetadata._metadata === 'object'
) {
return true;
}
return false;
};

View File

@ -0,0 +1,105 @@
export enum HISTORY_CODES {
//COMMON
//--FLOW
C1_ORDER = 101,
C2_ORDER = 102,
TRANSFER = 103,
COLLATERAL = 104,
BATCH = 105,
TAKE_ORDER = 106,
L1_TX = 107,
//--ERROR
ERROR = 200,
BAD_REQUEST = 201,
FORBIDDEN = 202,
NOT_FOUND = 203,
CONFLICT = 204,
CONTRACT_ERROR = 210,
NOT_IMPLEMENTED = 211,
TIMEOUT = 212,
BATCH_ERROR = 213,
//--SUCCESS
SUCCESS = 500,
BATCH_SUCCESS = 501,
//C1 Order Creation
//--ERROR
C1_ORDER_NOT_CREATED = 301,
//--SUCCESS
C1_ORDER_CREATED = 601,
//C1 Order Closing
//--ERROR
C1_ORDER_NOT_CLOSED = 302,
//--SUCCESS
C1_ORDER_DEACTIVATED = 605,
C1_ORDER_CLOSED = 606,
//C1 Order Lifecycle
//--ERROR
C1_ORDER_NOT_ACTIVE = 303,
C1_BAD_L1_TX = 321,
C1_L1_TX_HANDLING_ERROR = 322,
C1_L1_EVENT_ERROR = 313,
//--SUCCESS
C1_ORDER_USED = 612,
C1_ORDER_UPDATED = 613,
C1_ORDER_COMPLETED = 614,
C1_ORDER_EXPIRED = 608,
C1_L1_TX_HANDLED = 620,
C1_L1_TRANSFER_TX_HANDLED = 621,
C1_L1_TAKE_TX_HANDLED = 622,
//C2 Order Creation
//--ERROR
C2_ORDER_NOT_CREATED = 401,
//--SUCCESS
C2_ORDER_CREATED = 701,
//C2 Order Closing
//--ERROR
C2_ORDER_NOT_CLOSED = 403,
//--SUCCESS
C2_ORDER_CLOSED = 706,
C2_ORDER_DISABLED = 707,
//C2 Order Lifecycle
//--ERROR
C2_ORDER_NOT_ACTIVE = 402,
//--SUCCESS
C2_ORDER_USED = 703,
C2_ORDER_UPDATED = 704,
C2_ORDER_EXPIRED = 705,
//C2 Request Creation
//--ERROR
C2_REQUEST_NOT_CREATED = 411,
C2_FITTING_ORDER_NOT_FOUND = 413,
C2_BTC_NONCE_NOT_AVAILABLE = 414,
C2_L1_EVENT_ERROR = 415,
//--SUCCESS
C2_REQUEST_CREATED = 711,
C2_REQUEST_UPDATED = 712,
C2_REQUEST_FALLBACK_CALL = 713,
//C2 Order Lifecycle
//--ERROR
C2_L1_TX_HANDLING_ERROR = 420,
C2_BAD_L1_TX = 424,
C2_REQUEST_NOT_ACTIVE = 412,
C2_REQUEST_EXPIRED = 416,
//--SUCCESS
C2_L1_TX_HANDLED = 720,
C2_REQUEST_EXECUTED = 714,
//Collateral
//--ERROR
C2_COLLATERAL_DEPOSIT_FAILED = 431,
C2_COLLATERAL_WITHDRAW_FAILED = 432,
//--SUCCESS
C2_COLLATERAL_DEPOSIT = 731,
C2_COLLATERAL_WITHDRAW = 732,
C2_COLLATERAL_LOCKED = 733,
C2_COLLATERAL_UNLOCKED = 734,
}

View File

@ -0,0 +1 @@
export const HISTORY_ACCESS_FEE = 200n;

View File

@ -0,0 +1,5 @@
export * from './codes';
export * from './constants';
export * from './keys';
export * from './types';
export * from './utils';

View File

@ -0,0 +1,22 @@
import { ClaimKey } from '@coinweb/contract-kit';
export enum HistoryKey {
HISTORY_ITEM = 'HISTORY_ITEM',
HISTORY_ACCESS = 'HISTORY_ACCESS',
}
export const createHistoryAccessFirstPart = () => [HistoryKey.HISTORY_ACCESS];
export const creteHistoryAccessKey = (id: string) =>
({
first_part: createHistoryAccessFirstPart(),
second_part: [id],
}) satisfies ClaimKey;
export const createHistoryItemFirstPart = (historyId: string) => [HistoryKey.HISTORY_ITEM, historyId];
export const createHistoryItemKey = (historyId: string, timestamp: number, uniqueId: string | number, order: number) =>
({
first_part: createHistoryItemFirstPart(historyId),
second_part: [Number.MAX_SAFE_INTEGER - timestamp, order, uniqueId],
}) satisfies ClaimKey;

View File

@ -0,0 +1,21 @@
import { MergePartialWithRegular, UnionToIntersection } from '../../../../shared';
import { HISTORY_CODES } from '../codes';
import {
CollateralHistoryItem,
ExpandedHistoryItem,
HistoryAccess,
L1TxHistoryItem,
ShortHistoryItem,
} from './entities';
export type HistoryAccessClaimBody = HistoryAccess;
type RegularHistoryClaimFields = { code: HISTORY_CODES; txId: string };
export type HistoryItemClaimBody = UnionToIntersection<
| MergePartialWithRegular<ShortHistoryItem, RegularHistoryClaimFields>
| MergePartialWithRegular<ExpandedHistoryItem, RegularHistoryClaimFields>
| MergePartialWithRegular<CollateralHistoryItem, RegularHistoryClaimFields>
| MergePartialWithRegular<L1TxHistoryItem, RegularHistoryClaimFields>
>;

View File

@ -0,0 +1,73 @@
import { HISTORY_CODES } from '../codes';
export type ShortHistoryCode =
| HISTORY_CODES.BATCH_SUCCESS
| HISTORY_CODES.C1_ORDER_CREATED
| HISTORY_CODES.C1_ORDER_DEACTIVATED
| HISTORY_CODES.C1_ORDER_CLOSED
| HISTORY_CODES.C1_ORDER_UPDATED
| HISTORY_CODES.C1_ORDER_EXPIRED
| HISTORY_CODES.C1_ORDER_USED
| HISTORY_CODES.C1_ORDER_COMPLETED
| HISTORY_CODES.C2_ORDER_CREATED
| HISTORY_CODES.C2_ORDER_CLOSED
| HISTORY_CODES.C2_ORDER_NOT_ACTIVE
| HISTORY_CODES.C2_ORDER_USED
| HISTORY_CODES.C2_ORDER_UPDATED
| HISTORY_CODES.C2_ORDER_EXPIRED
| HISTORY_CODES.C2_ORDER_DISABLED
| HISTORY_CODES.C2_FITTING_ORDER_NOT_FOUND
| HISTORY_CODES.C2_REQUEST_CREATED
| HISTORY_CODES.C2_REQUEST_FALLBACK_CALL
| HISTORY_CODES.C2_REQUEST_NOT_ACTIVE
| HISTORY_CODES.C2_REQUEST_EXECUTED
| HISTORY_CODES.C2_REQUEST_EXPIRED;
export type ErrorHistoryCode =
| HISTORY_CODES.ERROR
| HISTORY_CODES.BAD_REQUEST
| HISTORY_CODES.FORBIDDEN
| HISTORY_CODES.NOT_FOUND
| HISTORY_CODES.CONFLICT
| HISTORY_CODES.CONTRACT_ERROR
| HISTORY_CODES.NOT_IMPLEMENTED
| HISTORY_CODES.TIMEOUT
| HISTORY_CODES.BATCH_ERROR
| HISTORY_CODES.C1_ORDER_NOT_CREATED
| HISTORY_CODES.C1_ORDER_NOT_CLOSED
| HISTORY_CODES.C1_ORDER_NOT_ACTIVE
| HISTORY_CODES.C1_L1_TX_HANDLING_ERROR
| HISTORY_CODES.C1_BAD_L1_TX
| HISTORY_CODES.C2_ORDER_NOT_CREATED
| HISTORY_CODES.C2_ORDER_NOT_CLOSED
| HISTORY_CODES.C2_ORDER_NOT_ACTIVE
| HISTORY_CODES.C2_REQUEST_NOT_CREATED
| HISTORY_CODES.C2_FITTING_ORDER_NOT_FOUND
| HISTORY_CODES.C2_BTC_NONCE_NOT_AVAILABLE
| HISTORY_CODES.C2_L1_TX_HANDLING_ERROR
| HISTORY_CODES.C2_BAD_L1_TX
| HISTORY_CODES.C2_L1_EVENT_ERROR
| HISTORY_CODES.C2_REQUEST_NOT_ACTIVE
| HISTORY_CODES.C2_REQUEST_EXPIRED
| HISTORY_CODES.C2_COLLATERAL_DEPOSIT_FAILED
| HISTORY_CODES.C2_COLLATERAL_WITHDRAW_FAILED;
export type CollateralHistoryCode =
| HISTORY_CODES.C2_COLLATERAL_DEPOSIT
| HISTORY_CODES.C2_COLLATERAL_WITHDRAW
| HISTORY_CODES.C2_COLLATERAL_DEPOSIT_FAILED
| HISTORY_CODES.C2_COLLATERAL_WITHDRAW_FAILED
| HISTORY_CODES.C2_COLLATERAL_LOCKED
| HISTORY_CODES.C2_COLLATERAL_UNLOCKED;
export type L1TxHistoryCode =
| HISTORY_CODES.C1_BAD_L1_TX
| HISTORY_CODES.C1_L1_TX_HANDLED
| HISTORY_CODES.C1_L1_TX_HANDLING_ERROR
| HISTORY_CODES.C2_BAD_L1_TX
| HISTORY_CODES.C2_L1_TX_HANDLED
| HISTORY_CODES.C2_L1_TX_HANDLING_ERROR
| HISTORY_CODES.C1_L1_TRANSFER_TX_HANDLED
| HISTORY_CODES.C1_L1_TAKE_TX_HANDLED;
export type UntypedHistoryCode = Exclude<HISTORY_CODES, CollateralHistoryCode | ShortHistoryCode | L1TxHistoryCode>;

View File

@ -0,0 +1,51 @@
import { HexBigInt } from '../../../../shared';
import { HISTORY_CODES } from '../codes';
import {
CollateralHistoryCode,
ErrorHistoryCode,
L1TxHistoryCode,
ShortHistoryCode,
UntypedHistoryCode,
} from './codes';
export type ShortHistoryItem<TCode extends ShortHistoryCode = ShortHistoryCode> = {
code: TCode;
links?: HistoryLink[] | null;
};
export type ExpandedHistoryItem<TCode extends UntypedHistoryCode = UntypedHistoryCode> = {
code: TCode;
message: string;
links?: HistoryLink[] | null;
};
export type CollateralHistoryItem<TCode extends CollateralHistoryCode = CollateralHistoryCode> = {
code: TCode;
message?: string;
amount: HexBigInt;
links?: HistoryLink[] | null;
};
export type L1TxHistoryItem<TCode extends L1TxHistoryCode = L1TxHistoryCode> = {
code: TCode;
message?: string;
l1TxId: string;
links?: HistoryLink[] | null;
};
export type HistoryItem = ShortHistoryItem | ExpandedHistoryItem | CollateralHistoryItem | L1TxHistoryItem;
export type ErrorHistoryItem =
| ShortHistoryItem<ShortHistoryCode & ErrorHistoryCode>
| ExpandedHistoryItem<UntypedHistoryCode & ErrorHistoryCode>
| CollateralHistoryItem<CollateralHistoryCode & ErrorHistoryCode>
| L1TxHistoryItem<L1TxHistoryCode & ErrorHistoryCode>;
export type HistoryAccess = {
historyId: string;
timestamp?: number;
};
export type HistoryLink = Required<HistoryAccess> & {
code: HISTORY_CODES;
};

View File

@ -0,0 +1,4 @@
export * from './claimsBody';
export * from './codes';
export * from './entities';
export * from './metadata';

View File

@ -0,0 +1,24 @@
import { HistoryLink } from './entities';
export type NewMetadataInterface = {
_newAccessId?: string;
_historyLink?: HistoryLink;
};
export type TrackingMetadataInterface = {
_trackingId: string;
_currentAccessId?: string;
_historyLink?: HistoryLink;
_historyOrder?: number;
};
export type ContractCallMetadataInterface = {
_metadata: NewMetadataInterface | TrackingMetadataInterface;
};
export type ContractCallMetadata = {
trackingId: string | null;
historyOrder: number | null;
historyLink: HistoryLink | null;
accessId: string | null;
};

View File

@ -0,0 +1,49 @@
import { ContractCallMetadataInterface, HistoryLink, NewMetadataInterface, TrackingMetadataInterface } from '../types';
export const constructMetadata = (
data:
| {
accessId: string;
historyLink?: HistoryLink;
}
| {
trackingId: string;
currentAccessId?: string;
historyLink?: HistoryLink;
historyOrder?: number;
}
): ContractCallMetadataInterface => {
if ('accessId' in data) {
const metadata: NewMetadataInterface = {
_newAccessId: data.accessId,
};
if (data.historyLink) {
metadata._historyLink = data.historyLink;
}
return {
_metadata: metadata,
};
}
const metadata: TrackingMetadataInterface = {
_trackingId: data.trackingId,
};
if (data.currentAccessId) {
metadata._currentAccessId = data.currentAccessId;
}
if (data.historyLink) {
metadata._historyLink = data.historyLink;
}
if (data.historyOrder) {
metadata._historyOrder = data.historyOrder;
}
return {
_metadata: metadata,
};
};

View File

@ -0,0 +1 @@
export * from './constructMetadata';

View File

@ -0,0 +1 @@
export * from './types';

View File

@ -0,0 +1,17 @@
import type { GqlIssuedClaim } from '@coinweb/wallet-lib';
export type Client = {
fetchClaims<T>(
firstPart: NonNullable<unknown>,
secondPart: T,
range?: {
start: T extends null ? unknown : T | null;
end: T extends null ? unknown : T | null;
}
): Promise<GqlIssuedClaim[]>;
};
export type Pagination = {
limit: number;
offset: number;
};

View File

@ -0,0 +1,2 @@
export * from './api';
export * from './uiCommands';

View File

@ -0,0 +1,13 @@
import { ContractCall, constructContractIssuer, prepareQueueContractCall } from '@coinweb/contract-kit';
export const constructCall = (
contractId: string,
methodName: string,
methodArgs: unknown[],
cost: bigint,
auth: boolean = true
): ContractCall => {
const issuer = constructContractIssuer(contractId);
return prepareQueueContractCall(issuer, { methodName, methodArgs }, cost, auth);
};

View File

@ -0,0 +1,5 @@
import { ContractCall } from '@coinweb/contract-kit';
export const constructUiCommand = (calls: ContractCall[]) => {
return JSON.stringify({ CustomV1: { calls } });
};

View File

@ -0,0 +1,2 @@
export * from './constructCall';
export * from './constructUiCommand';

View File

@ -0,0 +1 @@
export * from './features';

View File

@ -0,0 +1,20 @@
import { Context, extractContractInfo } from '@coinweb/contract-kit';
import { HISTORY_CODES } from '../../module/history/shared';
import { Exception } from '../features';
export const getCallParameters = (context: Context) => {
const { authenticated, providedCweb } = extractContractInfo(context.tx);
if (!providedCweb) {
throw new Exception({
code: HISTORY_CODES.BAD_REQUEST,
message: 'Cweb was not provided',
});
}
return {
availableCweb: providedCweb,
authInfo: authenticated,
};
};

View File

@ -0,0 +1,4 @@
import { Context, extractContractArgs } from '@coinweb/contract-kit';
export const getContractArguments = <TArguments extends unknown[]>(context: Context) =>
extractContractArgs(context.tx) as TArguments;

View File

@ -0,0 +1,3 @@
import { constructContractIssuer, Context, getContractId } from '@coinweb/contract-kit';
export const getContractIssuer = (context: Context) => constructContractIssuer(getContractId(context.tx));

View File

@ -0,0 +1,5 @@
import { constructContractRef, Context } from '@coinweb/contract-kit';
import { getContractIssuer } from './getContractIssuer';
export const getContractRef = (context: Context) => constructContractRef(getContractIssuer(context), []);

View File

@ -0,0 +1,4 @@
import { Context, getMethodArguments as cKitGetMethodArguments } from '@coinweb/contract-kit';
export const getMethodArguments = <TArguments extends unknown[]>(context: Context) =>
cKitGetMethodArguments(context).slice(1) as TArguments;

Some files were not shown because too many files have changed in this diff Show More