Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion ccip-cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Format } from './commands/index.ts'
util.inspect.defaultOptions.depth = 6 // print down to tokenAmounts in requests
// generate:nofail
// `const VERSION = '${require('./package.json').version}-${require('child_process').execSync('git rev-parse --short HEAD').toString().trim()}'`
const VERSION = '1.3.1-d5fea83'
const VERSION = '1.3.1-850eb05'
// generate:end

const globalOpts = {
Expand Down Expand Up @@ -52,6 +52,30 @@ const globalOpts = {
return arg // it's a URL string
},
},
'canton-jwt': {
type: 'string',
describe: 'JWT bearer token for Canton Ledger API authentication',
},
'canton-party': {
type: 'string',
describe: 'Daml party ID for Canton command submissions (e.g. participant1::12208...)',
},
'canton-eds-url': {
type: 'string',
describe: 'Base URL for the Canton Explicit Disclosure Service (EDS)',
},
'indexer-url': {
type: 'string',
describe: '(Optional) Base URL for the CCV indexer service',
},
'canton-ccip-party': {
type: 'string',
describe: 'Daml party ID for Canton CCIP interactions (e.g. participant1::12208...)',
},
'canton-transfer-instruction-url': {
type: 'string',
describe: 'Base URL for fetching transfer instructions from Canton (if different from EDS URL)',
},
} as const

/** Type for global CLI options. */
Expand Down
27 changes: 27 additions & 0 deletions ccip-cli/src/providers/canton.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { type CantonWallet, CCIPArgumentInvalidError } from '@chainlink/ccip-sdk/src/index.ts'

/**
* Loads a Canton wallet from the provided options.
*
* A Canton "wallet" is simply a Daml party ID. The party can be supplied via:
* - `--wallet <party>` (if the value contains `::`, it's treated as a party ID)
* - `--canton-party <party>` (explicit Canton party flag)
*
* @param opts - CLI options containing wallet and/or canton-party values.
* @returns A {@link CantonWallet} with the resolved party ID.
* @throws {@link CCIPArgumentInvalidError} if no valid party ID can be resolved.
*/
export function loadCantonWallet(opts: { wallet?: unknown; cantonParty?: string }): CantonWallet {
// Prefer --wallet if it looks like a Daml party ID (contains `::`)
if (typeof opts.wallet === 'string' && opts.wallet.includes('::')) {
return { party: opts.wallet }
}
// Fall back to --canton-party
if (opts.cantonParty) {
return { party: opts.cantonParty }
}
throw new CCIPArgumentInvalidError(
'wallet',
'Canton requires a Daml party ID via --wallet <party::hash> or --canton-party <party>',
)
}
55 changes: 52 additions & 3 deletions ccip-cli/src/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { existsSync, readFileSync } from 'node:fs'
import { readFile } from 'node:fs/promises'

import {
type CantonConfig,
type Chain,
type ChainGetter,
type ChainTransaction,
Expand All @@ -17,6 +18,7 @@ import {
} from '@chainlink/ccip-sdk/src/index.ts'

import { loadAptosWallet } from './aptos.ts'
import { loadCantonWallet } from './canton.ts'
import { loadEvmWallet } from './evm.ts'
import { loadSolanaWallet } from './solana.ts'
import { loadSuiWallet } from './sui.ts'
Expand Down Expand Up @@ -55,11 +57,33 @@ async function collectEndpoints(

export function fetchChainsFromRpcs(
ctx: Ctx,
argv: Pick<GlobalOpts, 'rpcs' | 'rpcsFile' | 'api'>,
argv: Pick<
GlobalOpts,
| 'rpcs'
| 'rpcsFile'
| 'api'
| 'cantonJwt'
| 'cantonParty'
| 'cantonEdsUrl'
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrevmatos we need somehow all these values from the user input, what's the recommended way to get them through the CLI?

This way I understand is not ideal

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Offchain services URLs could be hardcoded

| 'indexerUrl'
| 'cantonCcipParty'
| 'cantonTransferInstructionUrl'
>,
): ChainGetter
export function fetchChainsFromRpcs(
ctx: Ctx,
argv: Pick<GlobalOpts, 'rpcs' | 'rpcsFile' | 'api'>,
argv: Pick<
GlobalOpts,
| 'rpcs'
| 'rpcsFile'
| 'api'
| 'cantonJwt'
| 'cantonParty'
| 'cantonEdsUrl'
| 'indexerUrl'
| 'cantonCcipParty'
| 'cantonTransferInstructionUrl'
>,
txHash: string,
): [ChainGetter, Promise<[Chain, ChainTransaction]>]

Expand All @@ -74,9 +98,30 @@ export function fetchChainsFromRpcs(
*/
export function fetchChainsFromRpcs(
ctx: Ctx,
argv: Pick<GlobalOpts, 'rpcs' | 'rpcsFile' | 'api'>,
argv: Pick<
GlobalOpts,
| 'rpcs'
| 'rpcsFile'
| 'api'
| 'cantonJwt'
| 'cantonParty'
| 'cantonEdsUrl'
| 'indexerUrl'
| 'cantonCcipParty'
| 'cantonTransferInstructionUrl'
>,
txHash?: string,
) {
const cantonConfig: CantonConfig | undefined = argv.cantonJwt
? {
jwt: argv.cantonJwt,
party: argv.cantonParty ?? '',
edsUrl: argv.cantonEdsUrl ?? '',
indexerUrl: argv.indexerUrl,
ccipParty: argv.cantonCcipParty ?? '',
transferInstructionUrl: argv.cantonTransferInstructionUrl ?? '',
}
: undefined
const chains: Record<string, Promise<Chain>> = {}
const chainsCbs: Record<
string,
Expand Down Expand Up @@ -104,6 +149,7 @@ export function fetchChainsFromRpcs(
for (const url of endpoints) {
const chain$ = C.fromUrl(url, {
...ctx,
...(cantonConfig ? { cantonConfig } : {}),
apiClient:
argv.api === false ? null : typeof argv.api === 'string' ? argv.api : undefined,
})
Expand Down Expand Up @@ -222,6 +268,9 @@ export async function loadChainWallet(chain: Chain, argv: { wallet?: unknown; rp
chain.network.networkType === NetworkType.Testnet,
)
return [wallet.getAddress(), wallet] as const
case ChainFamily.Canton:
wallet = loadCantonWallet(argv)
return [wallet.party, wallet] as const
default:
// TypeScript exhaustiveness check - this should never be reached
throw new CCIPChainFamilyUnsupportedError((chain.network as { family: string }).family)
Expand Down
2 changes: 1 addition & 1 deletion ccip-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@
},
"dependencies": {
"@aptos-labs/ts-sdk": "^5.2.1",
"buffer": "^6.0.3",
"@coral-xyz/anchor": "^0.29.0",
"@mysten/bcs": "^1.9.2",
"@mysten/sui": "^1.45.2",
Expand All @@ -90,6 +89,7 @@
"bn.js": "^5.2.3",
"borsh": "^2.0.0",
"bs58": "^6.0.0",
"buffer": "^6.0.3",
"ethers": "6.16.0",
"got": "^11.8.6",
"micro-memoize": "^5.1.1",
Expand Down
2 changes: 2 additions & 0 deletions ccip-sdk/src/all-chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { AptosChain } from './aptos/index.ts'
import { CantonChain } from './canton/index.ts'
import { EVMChain } from './evm/index.ts'
import { SolanaChain } from './solana/index.ts'
import { SuiChain } from './sui/index.ts'
Expand All @@ -21,6 +22,7 @@ export const allSupportedChains = {
[ChainFamily.Aptos]: AptosChain,
[ChainFamily.Sui]: SuiChain,
[ChainFamily.TON]: TONChain,
[ChainFamily.Canton]: CantonChain,
}

export { supportedChains } from './supported-chains.ts'
2 changes: 1 addition & 1 deletion ccip-sdk/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const DEFAULT_TIMEOUT_MS = 30000
/** SDK version string for telemetry header */
// generate:nofail
// `export const SDK_VERSION = '${require('./package.json').version}-${require('child_process').execSync('git rev-parse --short HEAD').toString().trim()}'`
export const SDK_VERSION = '1.3.1-d5fea83'
export const SDK_VERSION = '1.3.1-850eb05'
// generate:end

/** SDK telemetry header name */
Expand Down
Loading
Loading